Django validate column combination existence (Unique with boolean field)

Viewed 810

I'm on Django 1.9. I've a simple model with:

#Goods
class Goods(models.Model):
    code = models.CharField(max_length=50)
    decription = models.CharField(max_length=100)
    ...etc

#Vendors
class Vendors(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100)
    ...etc

And a class to define the multiple vendors to obtain a good.

#Purchase_options
class PurchaseOptions(models.Model):
    preferred_vendor = models.BooleanField()
    vendor = models.ForeignKey(Vendors)
    good = models.ForeignKey(Goods)

Here's is the question: How can I make sure that only one vendor for a particular good can be set as preferred?.

Accepted values on table:

**Vendor | Product | Preferred**
  V_01   | Good_01 | True
  V_02   | Good_01 | False
  V_03   | Good_01 | False
  V_02   | Good_02 | True
  V_04   | Good_02 | False

Wrong values on table:

**Vendor | Product | Preferred**
  V_01   | Good_01 | True
  V_02   | Good_01 | **True**  <-There's already a preferred vendor.
  V_03   | Good_01 | False
  V_02   | Good_02 | True
  V_04   | Good_02 | False

I'm using Django's admin interface to fill-up the data on Puchase_Options. I tried this:

1) Define a validator that, given the Preferred value and the product id, checks if this combination exists in the table:

def validator(preferred, id):
    if Purchase_Option.objects.filter(good.id=id,preferred_vendor=preferred).exists():
        Raise ValidationError("There's already a preferred vendor defined for this product")

But it's telling me that object Purchase_Options doesn't exist. I believe I can't actually query the database or handle querysets within a validator function.

2) I tried using the meta property unique-together("preferred_vendor","good_id"). That would work except that I must allow multiple combinations of False + Good_Id (because I've many Non-Preferred vendors for a good)... but only just 1 combination of True+Good_id.

I don't really know what else to try and I'm really looking forward to hearing your ideas. You saved me in multiple occasions before :D

1 Answers
Related