[英]Django ManytoMany field duplicates, attribute error: 'ManyRelatedManager'
共有三種模型:House_Type,House_Option和Order
House_Type模型具有2個字段:id和name
House_Option具有3個字段:id,name和type,其中type是鏈接到House_Type的外鍵。
最后,Order由許多字段組成,其中一個字段是稱為“ choice”的ManytoMany字段,該字段鏈接到House_Option
這種工作方式是House_Type具有不同的房屋“類型”:例如,公寓,公寓,獨立式房屋,半獨立式房屋等。
House_Option具有每種類型的所有可能選項:例如,對於“公寓”類型,您的選項1位於街道X上,選項2位於街道Y上,依此類推。
在訂購模型中,用戶必須為每種房屋“類型”選擇一個“選項”。 因此,他們必須選擇一個公寓選項,一個房子選項等。因為這是ManytoMany字段,所以這是可能的。 但是我的問題是:例如,如何防止用戶選擇兩個“公寓”選項。 如何將它們限制為只能選擇一個(或不選擇)?
我試圖在Order模型中創建一個def(clean):
def clean(self):
if self.choice.house_option_type.count() > 1:
raise ValidationError('Custom Error Message')
但是,這將返回屬性錯誤:“ ManyRelatedManager”對象沒有屬性“ house_option_type”
有任何想法嗎?
通過明確定義的模型管理ManyToMany關系,其中兩個外鍵對於每個訂單都是唯一的。 您可以使用unique_together來對同一類型之間的多對多關系施加唯一性約束。
class House_Type(models.Model):
name = models.CharField(...)
class House_Option(models.Model):
name = models.CharField(...)
type = models.ForeignKey(House_Type)
class Order(models.Model):
...
choices = models.ManyToManyField(House_Option, through='Order_options')
...
class Order_options(models.Model):
class Meta:
unique_together = ('order', 'option__type')
...
order = models.ForeignKey(Order)
option = models.ForeignKey(House_Option)
...
編輯,更新語法和更正。
是的,看起來unique_together用作數據庫約束在表上,並且無法在表之間工作。 因此,請忽略上述方法。
我仍然認為以下應該起作用:
如果你簡單地覆蓋validate_unique上Order_options並實現自己獨特的邏輯,同時小心如何處理現有的和不存在的情況下,它應該工作。
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
class Order_options(models.Model):
...
def validate_unique(self, exclude = None):
super(Order_options, self).validate_unique(exclude)
options = { 'order__id' : self.order.id, 'option__type' : 'self.option.type' }
objs = Order_options.objects.exclude(id=self.id) if self.id else Order_options.objects
if objs.filter(**options).exists():
raise ValidationError({NON_FIELD_ERRORS: ['Error: {0} option type already exists'.format(self.option.type)]})
...
如果要計算類型選擇的數量,可以執行以下操作:
if self.choice.filter(type__name = 'condo').count() > 1:
raise ValidationError("Multiple condos selected!");
我認為Django不允許使用復合主鍵,並且(因此)也不允許復合外鍵約束(無論是主鍵還是唯一鍵)都不能解決問題。
該功能有一個票證,其中有活動: 票證#373:添加對多列主鍵的支持
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.