簡體   English   中英

Django ManytoMany字段重復,屬性錯誤:“ ManyRelatedManager”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM