【问题标题】:Add some data to extra_context in response_change在 response_change 中添加一些数据到 extra_context
【发布时间】:2022-07-01 14:14:56
【问题描述】:

我有一些模型:

from django.db import models


class Deviation(models.Model):
    name = models.CharField(max_length=100)

    def calc(self):
        # some calculation
        return 1

然后我添加了一个运行calc 方法的按钮(覆盖更改表单):

{% extends 'admin/change_form.html' %}

{% block submit_buttons_bottom %}
    {{ block.super }}
    <div class="submit-row">
            <input type="submit" value="Calculate" name="calc">
    </div>
    Calculation result: {{ result }}
{% endblock %}

这个模型在管理员中注册,处理calc按钮提交(通过extra_context):

@admin.register(Deviation)
class DeviationAdmin(admin.ModelAdmin):
    change_form_template = 'admin/deviations_change_form.html'
    list_display = '__str__',

    def response_change(self, request, obj):
        if "calc" in request.POST:
            obj.save()
            result = obj.calc()
            return self.change_view(request, str(obj.id), form_url='', extra_context={'result': result})
        return super().response_change(request, obj)

这里发生了问题(递归)。我无法通过extra_context 呈现带有结果的更改视图。

如何通过 extra_context 来改变视图?

【问题讨论】:

    标签: django


    【解决方案1】:

    根据您的代码,我假设您想在 response_change 的管理员更改表单上显示一些内容

    在成功的 POST 请求上呈现被认为是一种反模式,因为如果刷新或当用户按下浏览器上的后退按钮时可以重新提交表单

    最大的递归错误是因为 change_view 方法内部调用了 response_change 并且在您的代码中 response_change 方法再次调用了 change_view 导致没有退出条件或返回的递归

    我们可以使用 Django 缓存在重定向时显示额外内容,而无需像下面这样呈现

    1) 首先在settings.py中设置CACHES

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'unique-snowflake',
        }
    }
    

    其他类型的Django Caches请参考本文档

    2) 在 response_change 中使用 django 缓存,如下所示

    from django.core.cache import cache
    from django.http import HttpResponseRedirect
    
    @admin.register(Deviation)
    class DeviationAdmin(admin.ModelAdmin):
        ....
    
        def response_change(self, request, obj):
            if "calc" in request.POST:
                obj.save()
                result = obj.calc()
    
                # Caching results with unique key 
                # In the format result_<object_id>
                # timeout is optional
                cache.add("result_%s" % obj.id, result, timeout=30)
    
                return HttpResponseRedirect(".")
            return super().response_change(request, obj)
        ....
    

    3) 现在覆盖更改方法以从缓存中读取并传递 extra_content

    from django.core.cache import cache
    from django.http import HttpResponseRedirect
    
    @admin.register(Deviation)
    class DeviationAdmin(admin.ModelAdmin):
        ....
    
        def change_view(request, object_id, form_url="", extra_content={}):
            # Retrieving results from Django cache
            results = cache.get("result_%s" % object_id)
            if results:
                extra_content.update({"results":"results")
            return super().change_view(request, object_id, form_url, extra_content)
    
        def response_change(self, request, obj):
            if "calc" in request.POST:
                obj.save()
                result = obj.calc()
                
                # Caching results with unique key 
                # In the format result_<object_id>
                # timeout is optional
                cache.add("result_%s" % obj.id, result, timeout=30)
                
                return HttpResponseRedirect(".")
            return super().response_change(request, obj)
        ....
    

    我希望这对某人有所帮助,谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-09
      • 2013-07-07
      • 2017-04-23
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多