django - 仅在创建时排除 Django 模型的字段
问题描述
我正在为一家公司构建一个通知系统,管理员用户可以在其中创建项目并向其添加用户。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'。选项有:名称、许可证、项目编号、total_contract_hours。”
但是,当我打印可用字段时,它会返回一个带有所有模型属性作为键的 OrderedDict。我究竟做错了什么?谢谢!
解决方案
我想通了,该字段必须在 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): form = ProjectForm
def save_model(self, request, obj, form, change):
obj.design_manager = request.user
super().save_model(request, obj, form, change)
推荐阅读
- azure-devops - 如何在 Azure Devops 上获取存储库权限?
- sql - SQL Select 语句 - Automation Anywhere
- c - 为什么 GCC 编译器不支持 #pragma startup 和 #pragma exit 指令?
- python - 带有嵌入的 CNN - 高训练准确度和稳定的验证准确度
- pandas - Pyinstaller、Multiprocessing 和 Pandas - 没有这样的文件/目录
- sql-server - 如何确定 id 日期属于某个范围(范围存储在另一个表的单独行中)
- python - 如何将元组元组中的变量更改为具有所需值的元组
- javascript - 如何在云函数(Javascript)中从实时数据库中的字段值读取数据
- sql - Oracle SQL - 创建选择语句,它将检索每个月的结束日期,但比较月末后的一两天的值
- firebase - Google Ads 中缺少一些通过 Firebase 报告的 Google Analytics 4 转化