我们的动物模型具有三个属性:
- 狗名
- 猫名
- 猴子名字
其中一个必须填写(不再有!动物是狗、猫或猴子),如果我设置例如 cat_name,我希望停用 dog_name 和 monkey_name(用户不应设置多个名称)。
是否可以在 django admin 中设置它? 这个例子可能很愚蠢,但我试图解释我的意图 - 停用不必要的属性。
如果可能的话,我会尽量避免涉及冗余字段的数据库模式。考虑一个单独的“动物类型”表,在你的动物表中有一个 fkey。
所以:
动物类型:
id type_name
1 cat
2 dog
3 monkey
动物:
id name type
1 kitty 1
2 fido 2
3 rover 2
4 mr banannas 3
等等,从长远来看会为您减轻痛苦
编辑:要在下面回答您的进一步评论,您可以尝试覆盖模型的 clean() 函数,所以
class YourModel(models.Model):
first_property = models.FileField()
second_property = models.ImageField()
def clean(self)
from django.core.exceptions import ValidationError
if self.first_property.name not in ['', None] and \
self.second_property.name not in ['', None]:
raise ValidationError('Cannot have a first_property and a second_property!.')
每当您尝试保存模型时,这将引发错误消息,尽管它不会阻止他们在表单中实际输入这两个值。
假设您知道您想要什么,您可以创建模型代理,向 Django 管理员注册它们并使用exclude
,fields
或fieldsets
管理员模型中的属性停用不必要的字段。
# models.py
class Animal(models.Model):
dog_name = models.CharField()
cat_name = models.CharField()
monkey_name = models.CharField()
class Dog(models.Model):
class Meta:
proxy = True
class Cat(models.Model):
class Meta:
proxy = True
class Monkey(models.Model):
class Meta:
proxy = True
# admin.py
class DogAdmin(models.Model):
exclude = ['cat_name', 'monkey_name']
class CatAdmin(models.Model):
fields = ['cat_name', 'other_field']
class MonkeyAdmin(models.Model):
exclude = ['cat_name', 'monkey_name']
admin.site.register(Dog, DogAdmin)
admin.site.register(Cat, CatAdmin)
admin.site.register(Monkey, MonkeyAdmin)
如果不同的动物代表存储在数据库中的不同事物,那么您可能只想使用它们自己的表创建单独的模型对象,并使用GenericForignKeys将它们链接在一起。
这增加了各种复杂性,但 django 更擅长处理常见的事情而不是不寻常的事情,而且看起来你想要存储信息的方式(这实际上是很常见的恕我直言)对于传统的关系数据库来说是困难的。
解决此问题的另一种方法是添加 javascript,当您设置一个时禁用“其他”字段。然后,您可以在表单/模型验证中强制执行此操作。
但我应该说,如果它可以应用于您的问题,我认为处理这个问题的最佳方法是 PT114 建议的方式。