Django模型中互斥的多对多关系

时间:2017-04-27 12:17:53

标签: python django django-models many-to-many constraints

我试图创建一个简单的模型来跟踪Django 1.10中的折扣优惠券(以Postgres 9.5作为底层数据库),我想知道是否有办法确保优惠券实例id,也许是一个更准确的术语?)不会同时出现在两个M2M关系中。

我确定每个人都熟悉优惠券的工作方式,但为了以防万一,让我解释一下用例

  1. 总是应用一些优惠券。例如:"您的首次购买免费送货" ,或"百事可乐在您的余生中享受10%的折扣" 。 ......那样的事情。
  2. 其他一些优惠券将通过代码(一个简单的字符串,真的)应用,用户必须在某处输入(例如"使用代码获得5%的折扣" 5-关闭"" ...是的,我可能不得不对代码进行模糊处理: - D
  3. 用户可以说"不,我不想将此优惠券应用于此订单,我稍后将使用它" 。例如:如果用户可以使用一次性5%折扣优惠券,但希望将其保留用于大量购买。让我们说客户知道他将在未来做出大笔购买,而现在他正在做一个小的购买。他可能想为后来(更大)的购买保留5%的折扣。
  4. 为了跟踪这些事情,我有一个这样的模型:

    class CouponTracker(models.Model):
        # Coupons that require a code to be activated:
        extra_applied_coupons = ManyToManyField('Coupon', related_name='+')
    
        # Coupons that the user could have applied and specifically
        # said no (such as 5% off if the purchase is small, and wants
        # to use it later):
        vetoed_coupons = ManyToManyField('Coupon', related_name='+')
    

    所以,问题是:

    如何(在数据库级别,通过约束)强制优惠券不会同时出现在extra_applied_couponsvetoed_coupons中?

    提前谢谢!

2 个答案:

答案 0 :(得分:1)

为什么不将2 extra_applied_couponsvetoed_coupons合并,还有1个字段(例如type)来确定优惠券组。然后问题会更简单,只需确保1 ManyToMany关系中的唯一性

class CouponTracker(models.Model):
    coupons = ManyToManyField('Coupon', related_name='+')
    type = models.IntegerField(default=0)

type对于extra_applied_coupons可以为0,对于vetoed_coupons可以为1。 如果您想添加更多关系属性,可以查看https://docs.djangoproject.com/en/1.11/topics/db/models/#extra-fields-on-many-to-many-relationships

答案 1 :(得分:0)

由于ManyToMany关系创建了一个单独的表,因此AFAIK不能在表之间建立UNIQUE约束。所以没有直接的方法来添加数据库级别的约束。检查this。您必须在应用程序层或像this

这样的hackish方式上做