我有一套模型,关于餐馆和运营它们的厨师 * :
class Chef(models.Model):
name = models.TextField()
class Restaurant(models.Model):
name = models.TextField()
chef = models.ForeignKey(Chef)
class FrenchChef(Chef):
angryness = models.PositiveIntegerField()
class FrenchRestaurant(Restaurant):
region = models.TextField()
不幸的是,这个当前模型意味着非FrenchChef
可以运行FrenchRestaurant
。
我是否可以将子类模型的ForeignKey
的查询集限制为父类可用的子集?
*我的建模实际上并不是厨师和餐馆,但这更容易解释。这可能看起来不太明显,但Chef
和FrenchChef
确实需要以不同方式建模。
答案 0 :(得分:1)
如果您关注
,可以尝试定义干净的方法class FrenchRestaurant(models.Model):
# ...
def clean(self):
if not isinstance(self.chief, FrenchChief):
raise ValidationError()
答案 1 :(得分:1)
通过这样做:
class FrenchChef(Chef):
angryness = models.PositiveIntegerField()
除了Chef
之外,您还要在数据库中再创建一个表。在此处阅读有关模型继承类型的信息:https://docs.djangoproject.com/en/1.7/topics/db/models/#model-inheritance
我认为你应该为厨师创建一个表,为餐馆创建一个表,这里不需要继承:
class Chef(models.Model):
name = models.TextField()
# all chefs with not null angryness is frenchchefs...
# but you can add some field to explicitly save chef type
angryness = models.PositiveIntegerField(null=True)
class Restaurant(models.Model):
name = models.TextField()
chef = models.ForeignKey(Chef)
region = models.TextField()
# rtype added here but it is not necessarily
rtype = models.IntegerField(choices=restaurans_types)
选择的限制(过滤)应采用以下形式:
class FrenchRestaurantForm(forms.ModelForm):
def __init__(self, *args,**kwargs):
super (FrenchRestaurantForm, self ).__init__(*args,**kwargs)
self.fields['chef'].queryset = Chef.objects.filter(
angryness__gte=MIN_ANGRYNESS_LVL)
def save(commit=True):
model = super(FrenchRestaurantForm, self).save(commit=False)
model.rtype = SomeFrenchRestTypeConst
if commit:
model.save()
return model
class Meta:
model = Restaurant
要检查用户输入,您可以在表单字段https://docs.djangoproject.com/en/1.7/ref/forms/validation/#cleaning-a-specific-field-attribute
中添加干净方法如果故意创建了FrenchChef
(它是数据库中的不同表),那么您应该将其添加到FrenchRestaurant
(另一个表 - >另一个fk id):
class FrenchRestaurant(Restaurant):
region = models.TextField()
frenchchef = models.ForeignKey(FrenchChef)
答案 2 :(得分:1)
就像我在评论中提到的那样,你可以看看django模型数据验证方法。刚刚在这篇文章中找到另一个注释。 Adding Custom Django Model Validation
以下是执行验证后的常见模式。代码段是从上面提到的帖子中的一个答案中提取的。由https://stackoverflow.com/users/247542/cerin
回答
class BaseModel(models.Model):
def clean(self, *args, **kwargs):
# add custom validation here
super(BaseModel, self).clean(*args, **kwargs)
def save(self, *args, **kwargs):
self.full_clean()
super(BaseModel, self).save(*args, **kwargs)

您可以继续阅读有关django文档中验证的更多信息。
如果您正在寻找可能存在的任何基于类型/固有的解决方案。我不确定它们是否存在。我还是想看看是否有人在django中提出这样的规定。