【问题标题】:Exclude fields for Django model, only on creation仅在创建时排除 Django 模型的字段
【发布时间】:2019-05-05 16:56:05
【问题描述】:

我正在为一家公司构建一个通知系统,管理员用户可以在其中创建项目并向其添加用户。 Project 模型有 9 个属性,但我只想在创建项目时显示 3 或 4 个字段,但在更新现有项目时显示它们。

这个变化只需要反映在 Django 管理站点上,所以我用我自己的 ProjectForm 扩展了 ProjectAdmin,在这里我扩展了 init 方法来检查它是否是一个新实例,并且如果是这样,请删除某些字段。

# models.py
class Project(models.Model):
    project_number = models.IntegerField()
    name = models.CharField(max_length=100)
    permit = models.CharField(max_length=100, blank=True, default='')
    is_active = models.BooleanField(default=True)
    users = models.ManyToManyField(CustomUser, blank=True, related_name='project_users')
    # add a default

    levels = models.ManyToManyField('Level', blank=True, related_name='project_levels')

    total_contract_hours = models.IntegerField(default=0, blank=True, verbose_name='Total Design Hours')
    hours_used = models.IntegerField(default=0, blank=True, verbose_name='Total Design Hours Used')

    notes = models.ManyToManyField('notes.ProjectNote', related_name='core_project_notes', blank=True)

    history = HistoricalRecords()

    def __str__(self):
        ret_str = "{} {}".format(self.project_number, self.name)
        if self.permit:
            ret_str += "  |  Permit: {}".format(self.permit)
        return ret_str



# admin.py
class ProjectForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(ProjectForm, self).__init__(*args, **kwargs)
        attrs = {'class': 'form-control', 'required': True}
        if self.instance and self.instance.pk is None:
            # creating project

            exclude = ['is_active', 'users', 'levels', 'hours_used', 'notes']
            for field in exclude:
                try:
                    del self.fields[field]
                except ValueError:
                    print('{} does not exist'.format(field))

        for field in self.fields.values():
            field.widget.attrs = attrs

    class Meta:
        model = Project
        fields = ['project_number', 'name', 'total_contract_hours']


class ProjectAdmin(admin.ModelAdmin):
    form = ProjectForm
    fields = ['project_number', 'name', 'permit', 'is_active', 'users', 'levels', 'total_contract_hours', 'hours_used', 'notes']

正如我所说,我只想要创建时的基本项目字段,但在更新现有项目时显示所有属性。仅通过这些更改,我现在得到一个 KeyError:

KeyError:“在 'ProjectForm' 中找不到键 'is_active'。选项有: 名称、许可证、project_number、total_contract_hours。”

但是,当我打印可用字段时,它会返回一个带有所有模型属性作为键的 OrderedDict。我究竟做错了什么?谢谢!

【问题讨论】:

  • 您的逻辑似乎错误。也许你的意思是if not self.instance or self.instance.pk is None:
  • 感谢您的回复!不幸的是,这并没有解决问题。它目前所说的唯一可用属性的字段是我之前添加到 exclude 变量中的 4 个字段,但是,这影响了创建和更新,所以我试图解决这个问题,但我一直收到那个 KeyError。会不会和 Django 缓存对象的方式有关?
  • 当您使用 super(ProjectForm) 实例化表单时,会实例化一个 Project 对象还是在您创建表单时实例未完全实例化?

标签: django forms model


【解决方案1】:

我想通了,该字段必须在 Meta 中列出,然后您只需将该字段设置为隐藏字段。

类 ProjectForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
    super(ProjectForm, self).__init__(*args, **kwargs)
    print("Adding project")

    if not self.instance or self.instance.pk is None:
        for name, field in self.fields.items():
            if name in ['design_manager', ]:
                field.widget = forms.HiddenInput()

class Meta:
    model = Project
    fields = ['project_number', 'name', 'design_manager', 'total_contract_hours']

类 ProjectAdmin(admin.ModelAdmin): 表格 = 项目表格

def save_model(self, request, obj, form, change):
    obj.design_manager = request.user
    super().save_model(request, obj, form, change)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 2019-06-08
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2015-04-16
    • 1970-01-01
    相关资源
    最近更新 更多