fredperk
fredperk

Reputation: 818

Django: substitute unique_together with UniqueConstraint

I am trying to enforce a constraint upon a Vote model in my Django application, namely that a user cannot vote more than once the same object.

To do so I am using unique_together:

class Vote(models.Model):
    vote = models.SmallIntegerField(choices=VOTES, null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE,
        related_name="user_votes")
    definition = models.ForeignKey(Definition, on_delete=models.CASCADE,
        related_name="definition_votes")

    class Meta:
        # Ensure user cannot vote more than once.
        unique_together = ["user", "definition"]

This works, I think.

However, in Django's documentation for unique_together it is noted that

UniqueConstraint provides more functionality than unique_together. unique_together may be deprecated in the future.

How can I substitute the above code using unique_together with code using UniqueConstraint?

Upvotes: 2

Views: 1018

Answers (2)

Nelson
Nelson

Reputation: 2186

The biggest confusion is the UniqueConstraint documentation can be arrived at directly from unique_togther, but it skips the Metas.constraint documentation:

constraints

Options.constraints

A list of constraints that you want to define on the model:
from django.db import models

class Customer(models.Model):
    age = models.IntegerField()

    class Meta:
        constraints = [
            models.CheckConstraint(check=models.Q(age__gte=18), name='age_gte_18'),
        ]

The sample code quickly tells you how to use the constraints.

Upvotes: 0

iklinac
iklinac

Reputation: 15748

Simply add a UniqueConstraint instead:

class Meta:
    constraints = [
            UniqueConstraint(
                 fields=['user', 'definition'], 
                 name='unique_vote'
            )
    ]

Upvotes: 6

Related Questions