如何在 Django ModelAdmin 中创建和保存动态字段?

2023-11-29

我有一些模型:

class GroupType(models.Model):
    name = models.CharField(max_length=255)

class Group(models.Model):
    name = models.CharField(max_length=255)
    group_type = models.ForeignKey(GroupType)

class Person(models.Model):
    name = models.CharField(max_length=255)
    groups = models.ManyToManyField(Group, related_name="+")

但在 ModelAdmin 中,我想为每个组类型动态添加字段。所以如果我有两种组类型public, private,我希望管理表单显示两个字段public_groups and private_groups而不是实际的数据库字段groups.

更多信息

我尝试创建自定义表单来动态添加字段:

class PersonAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PersonAdminForm, self).__init__(*args, **kwargs)
        new_fields = {}
        for group_type in GroupType.objects.all():
            field_name = "{0}_groups".format(group_type.name.lower())
            qs = Group.objects.filter(group_type=group_type)
            field_field = forms.ModelMultipleChoiceField(queryset=qs)
            new_fields[field_name] = field_field
        self.fields.update(new_fields)

    class Meta:
        model = Person
        fields = '__all__'

就将字段添加到表单而言,这似乎可以解决问题。但是保存这些字段并将它们添加到PersonAdmin不起作用。如果我将字段显式添加到fields属性上的PersonAdmin I get:

FieldError: Unknown field(s) (public_groups, private_groups) specified for Person. Check fields/fieldsets/exclude attributes of class PersonAdmin.

当尝试通过自定义“动态”添加它们时,我也得到了同样的结果get_formsets method:

def get_fieldsets(self, request, obj=None):
    fieldsets = super(PersonAdmin, self).get_fieldsets(request, obj)
    print(self.form.fields)
    fieldsets[0][1]['fields'].extend(['public_groups', 'private_groups'])
    return fieldsets

以下代码完美运行。被重写的__init__ and clean上的方法ModelForm添加动态字段并定义应如何保存值。

被重写的get_form and get_fieldsetsfieldsets属性上的AdminModel确保动态表单字段显示在管理中。

class PersonAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PersonAdminForm, self).__init__(*args, **kwargs)
        new_fields = {}
        initial = self.instance.groups.all()
        for group_type in GroupType.objects.all():
            field_name = '{0}_groups'.format(group_type.name.lower())
            qs = Group.objects.filter(group_type=group_type)
            field = forms.ModelMultipleChoiceField(
                queryset=qs,
                required=False,
                initial=initial,
            )
            new_fields[field_name] = field
        self.fields.update(new_fields)

    def clean(self):
        cleaned_data = super(PersonAdminForm, self).clean()
        groups = []
        for group_type in GroupType.objects.all():
            gt_name = '{0}_groups'.format(group_type.name.lower())
            groups.extend(cleaned_data.get(gt_name))
        self.instance.groups.clear()
        self.instance.groups.add(*groups)
        return cleaned_data

    class Meta:
        model = Person
        fields = '__all__'


@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    form = PersonAdminForm

    # using the fieldsets attribute instead of fields in order to dynamically
    # add group type fields later.
    fieldsets = (
        (None, {
            'fields': (
                'name',
            ),
        }),
    )

    def get_form(self, request, obj=None, **kwargs):
        kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
        return super(PersonAdmin, self).get_form(request, obj, **kwargs)

    def get_fieldsets(self, request, obj=None):
        fieldsets = super(PersonAdmin, self).get_fieldsets(request, obj)
        newfieldsets = list(fieldsets)
        fields = []
        for group_type in GroupType.objects.all():
            fields.append('{0}_groups'.format(group_type.name.lower()))
        newfieldsets.append(['Groups', {'fields': fields}])
        return newfieldsets
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Django ModelAdmin 中创建和保存动态字段? 的相关文章

  • 使用 openCV 对图像中的子图像进行通用检测

    免责声明 我是计算机视觉菜鸟 我看过很多关于如何在较大图像中查找特定子图像的堆栈溢出帖子 我的用例有点不同 因为我不希望它是具体的 而且我不确定如何做到这一点 如果可能的话 但我感觉应该如此 我有大量图像数据集 有时 其中一些图像是数据集的
  • 如何在 success_url 中传递上下文数据?

    我制作了一个表单 我希望再次返回相同的表单 这次使用可在我的模板中使用的上下文数据来显示表单已成功发送 我怎样才能做到这一点 class ContactUsView FormView form class ContactUsForm tem
  • 更改自动插入 tkinter 小部件的文本颜色

    我有一个文本框小部件 其中插入了三条消息 一条是开始消息 一条是结束消息 一条是在 单位 被摧毁时发出警报的消息 我希望开始和结束消息是黑色的 但被毁坏的消息 参见我在代码中评论的位置 插入小部件时颜色为红色 我不太确定如何去做这件事 我看
  • 为 pandas 数据透视表中的每个值列定义 aggfunc

    试图生成具有多个 值 列的数据透视表 我知道我可以使用 aggfunc 按照我想要的方式聚合值 但是如果我不想对两列求和或求平均值 而是想要一列的总和 同时求另一列的平均值 该怎么办 那么使用 pandas 可以做到这一点吗 df pd D
  • 在循环中每次迭代开始时将变量重新分配给原始值(在循环之前定义)

    在Python中 你使用 在每次迭代开始时将变量重新分配给原始值 在循环之前定义 时 也就是说 original 1D o o o for i in range 0 3 new original 1D revert back to orig
  • 在pyyaml中表示具有相同基类的不同类的实例

    我有一些单元测试集 希望将每个测试运行的结果存储为 YAML 文件以供进一步分析 YAML 格式的转储数据在几个方面满足我的需求 但测试属于不同的套装 结果有不同的父类 这是我所拥有的示例 gt gt gt rz shorthand for
  • python 集合可以包含的值的数量是否有限制?

    我正在尝试使用 python 设置作为 mysql 表中 ids 的过滤器 python集存储了所有要过滤的id 现在大约有30000个 这个数字会随着时间的推移慢慢增长 我担心python集的最大容量 它可以包含的元素数量有限制吗 您最大
  • Pandas Dataframe 中 bool 值的条件前向填充

    问题 如何转发 fill boolTruepandas 数据框中的值 如果是当天的第一个条目 True 到一天结束时 请参阅以下示例和所需的输出 Data import pandas as pd import numpy as np df
  • HTTPS 代理不适用于 Python 的 requests 模块

    我对 Python 还很陌生 我一直在使用他们的 requests 模块作为 PHP 的 cURL 库的替代品 我的代码如下 import requests import json import os import urllib impor
  • 如何将 numpy.matrix 提高到非整数幂?

    The 运算符为numpy matrix不支持非整数幂 gt gt gt m matrix 1 0 0 5 0 5 gt gt gt m 2 5 TypeError exponent must be an integer 我想要的是 oct
  • ExpectedFailure 被计为错误而不是通过

    我在用着expectedFailure因为有一个我想记录的错误 我现在无法修复 但想将来再回来解决 我的理解expectedFailure是它会将测试计为通过 但在摘要中表示预期失败的数量为 x 类似于它如何处理跳过的 tets 但是 当我
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • Nuitka 未使用 nuitka --recurse-all hello.py [错误] 编译 exe

    我正在尝试通过 nuitka 创建一个简单的 exe 这样我就可以在我的笔记本电脑上运行它 而无需安装 Python 我在 Windows 10 上并使用 Anaconda Python 3 我输入 nuitka recurse all h
  • 如何在 Django 中使用并发进程记录到单个文件而不使用独占锁

    给定一个在多个服务器上同时执行的 Django 应用程序 该应用程序如何记录到单个共享日志文件 在网络共享中 而不保持该文件以独占模式永久打开 当您想要利用日志流时 这种情况适用于 Windows Azure 网站上托管的 Django 应
  • 设置 torch.gather(...) 调用的结果

    我有一个形状为 n x m 的 2D pytorch 张量 我想使用索引列表来索引第二个维度 可以使用 torch gather 完成 然后然后还设置新值到索引的结果 Example data torch tensor 0 1 2 3 4
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • 用于运行可执行文件的python多线程进程

    我正在尝试将一个在 Windows 上运行可执行文件并管理文本输出文件的 python 脚本升级到使用多线程进程的版本 以便我可以利用多个核心 我有四个独立版本的可执行文件 每个线程都知道要访问它们 这部分工作正常 我遇到问题的地方是当它们
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql
  • Python:元类属性有时会覆盖类属性?

    下面代码的结果让我感到困惑 class MyClass type property def a self return 1 class MyObject object metaclass MyClass a 2 print MyObject
  • Pandas 与 Numpy 数据帧

    看这几行代码 df2 df copy df2 1 df 1 df 1 values 1 df2 ix 0 0 我们的教练说我们需要使用 values属性来访问底层的 numpy 数组 否则我们的代码将无法工作 我知道 pandas Data

随机推荐