简体   繁体   中英

Django unique_together not preventing duplicates

I am clearly not understanding how to do this correctly, can someone set me straight. Here is the model:

class Team(models.Model):
   teamID=models.CharField(max_length=255) #this will be generated on the iPad
   name=models.CharField(max_length=255)
   slug=models.SlugField(max_length=50) 
   teamNumber=models.CharField(max_length=30)
   checkIn=models.DateTimeField(default=datetime.now())
   totalScore=models.IntegerField(max_length=6) 

   class Meta:
       unique_together = ("teamID", "name", "slug", "teamNumber", "totalScore")

If I submit twice in a row it saves all of it. Yikes!!!

As aganders3 mentions the constraint is enforced at the database level; I assume though that you are using a database like SQLite that doesn't support this kind of constraint.

The reason that it all works as expected through the admin is that it is doing the uniqueness check itself (it doesn't rely strictly on the database to signal constraint violations).

You can switch to a database engine that supports this kind of uniqueness constraint (either MySQL or Postgres would work) or you could look at adding the check in using signals: http://djangosnippets.org/snippets/1628/

Try the proper nested-tuple syntax ((foo,bar),) instead of just (foo, bar) ?

https://docs.djangoproject.com/en/dev/ref/models/options/#unique-together

Yes the paremeter unique_together receives as input a tuple of tuples, I have not tested tuples of more than two elements but it should work

for your example:

unique_together = (("teamID", "name"), ("slug", "teamNumber"))

or:

unique_together = (("teamID", "name", "slug", "teamNumber", "totalScore"))

I found this approach helpful without adding any unnecessary fields

class Request(models.Model):
    user = models.ForeignKey(User, related_name='request_list', on_delete=models.CASCADE)
    requested_user = models.ForeignKey(User, on_delete=models.CASCADE)
    request_date = models.DateField(default=timezone.now())
    request_status = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        # Checking for duplicate requests
        try:
            request = Request.objects.get(user=self.user, requested_user=self.requested_user)
            raise ValidationError('Duplicate Value', code='invalid')
        except self.DoesNotExist:
            super().save(*args, **kwargs)

        # Checking for reversed duplicate requests
        try:
            request_new = Request.objects.get(requested_user=self.user, user=self.requested_user)
            raise ValidationError('Duplicate Value', code='invalid')
        except self.DoesNotExist:
            super().save(*args, **kwargs)

    def __str__(self):
        return self.user.username + '------>' + self.requested_user.username

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM