【问题标题】:dynamicly change part of form in django admin在 django admin 中动态更改表单的一部分
【发布时间】:2020-05-13 14:55:20
【问题描述】:

我有一个 jsonField 类型的模型,如下所示

class Product(models.Model):
    name=models.CharField(max_length=255,null=False,blank=False)
    description=models.TextField(max_length=500,null=True,blank=True)
    category=models.ForeignKey(Category,null=False,on_delete=models.CASCADE)

    values = JSONField()

以及包含此json字段所需的JsonSchema的类别模型如下:

class Category(models.Model):
    category_name=models.CharField(max_length=255,unique=True)
    type = models.ForeignKey(Type, on_delete=models.CASCADE)
    attributes_Schema_name = models.CharField(max_length=255)

    def __str__(self):
        return self.category_name

我制作了如下管理表单:

def Make_ProductJSONModelAdminForm(cat_id):
    class ProductJSONModelAdminForm(forms.ModelForm):
        class Meta:
            model = Product
            fields = "__all__"
            DATA_SCHEMA_name=Category.objects.values_list('attributes_Schema_name',flat=True).get(id=int(cat_id))
            with open("attSchemas/{0}".format(DATA_SCHEMA_name)) as jfile:
                DATA_SCHEMA=json.load(jfile)
            widgets = {
                'values': JSONEditorWidget(DATA_SCHEMA, collapsed=False),
            }
    return ProductJSONModelAdminForm


@admin.register(Product)
class ProductModelAdmin(admin.ModelAdmin):

    form = Make_ProductJSONModelAdminForm(cat_id=2)
    inlines = [productUnitInline, productImageInline]

问题是:当在管理员中选择类别时,我需要动态传递 cat_id=2。实际上,我需要在管理员的类别选择中动态获取下面代码中的 cat_id。

form = Make_ProductJSONModelAdminForm(cat_id=2)

我想知道这可能吗?

【问题讨论】:

    标签: django forms widget django-admin


    【解决方案1】:

    在每个 Django ModelAdmin 类中,您可以使用此签名覆盖创建表单的方法:

    @admin.register(Product)
    class ProductModelAdmin(admin.ModelAdmin):
        ...
    
        get_form(self, request, obj=None, **kwargs):
            DATA_SCHEMA = ...
            widget = JSONEditorWidget(DATA_SCHEMA, collapsed=False)
            Form = modelform_factory(Product, widgets={'value': widget})
            return Form
    

    您可以在此处添加构建表单所需的所有业务逻辑,例如cat_id 的初始值。 modelform factory 记录在here

    通过阅读您的代码,您打算配置一个小部件来为 JSON 模型字段呈现一些表单字段。或者,您可以使用 django-entangled 应用程序,它正是这样做的(免责声明:我是该库的作者)。

    【讨论】:

    • 感谢您的回答,但我仍然有问题,请您查看我的 seconf 答案吗?
    【解决方案2】:

    @jrief,我根据您的回答更改了我的 ProductModelAdmin,如下所示:

    @admin.register(Product)
    class ProductModelAdmin(admin.ModelAdmin):
    
        def get_form(self, request, obj=None, change=False, **kwargs):
            catid = request.GET.get('id', 1)
    
            DATA_SCHEMA_name = Category.objects.values_list('attributes_Schema_name', flat=True).get(id=int(catid))
            with open("attSchemas/{0}".format(DATA_SCHEMA_name)) as jfile:
                DATA_SCHEMA = json.load(jfile)
            form = super().get_form(request, obj,
                                    widgets={
                                        'values': JSONEditorWidget(DATA_SCHEMA, collapsed=False),
                                    }
                                    , **kwargs)
            # kwargs['form'] = form
            return form
    

    我在 change_form.html 上添加了以下代码以更改类别更改选择的表单:

    {% extends "admin/change_form.html" %}
    
    {% block extrahead %}
        {{ block.super }}
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script type="text/javascript" charset="utf-8">
            $(function(){
                // inspect html to check id of category select dropdown.
                $(document).on('change', "select#id_category", function(){
                    $.get($(location).attr('href'),{id: $(this).val()});
    
                 });
             });
        </script>
    {% endblock %}
    

    但问题是当我更改类别时,管理页面中没有任何变化。实际上我认为表单不会重新加载。有什么问题?

    【讨论】:

      猜你喜欢
      • 2011-05-16
      • 2012-02-28
      • 2011-07-11
      • 2021-12-08
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 2013-11-04
      相关资源
      最近更新 更多