Saif eldeen Adel
Saif eldeen Adel

Reputation: 388

How do i go about making a django model field unique but only for individual users?

So I have this watchlist model

class Watchlist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='watchlist')
    symbol = CharField(max_length=10, unique=True)

Where a user and a text symbol is saved. A user is not allowed to save two of the same symbol cuz that wouldnt be good logic. Thats why i added the unique=True. However, I later realized that i kinda misunderstood what unique does and that its unique across the whole table no matter who the user is.

I only want it to be unique when the user is the same.

So Test_User can save "ABC" and "DEF" but cant save "ABC" again. However User123 should be allowed to save "ABC" and so on.

One bad solution to this would be taking care of it in my views when i save instances by getting a list of symbols saved already and checking if the given symbol is in that list or not and save accordingly. I consider this a bad solution because it wont work in admin and the redundancy will be insane if i need to use it in other views

Upvotes: 1

Views: 1276

Answers (2)

Armen Tsaturyan
Armen Tsaturyan

Reputation: 111

Use unique_together field in Meta class for your model. For example:

class Watchlist(models.Model):
   user = models.ForeignKey(User, on_delete=models.CASCADE, 
                            related_name='watchlist')
   symbol = CharField(max_length=10)
   
   class Meta:
      unique_together = 'user', 'symbol'

Also link to Django docs: https://docs.djangoproject.com/en/3.1/ref/models/options/#unique-together

Upvotes: 2

Vishal Singh
Vishal Singh

Reputation: 6234

You can use UniqueConstraint[Django-Docs] to restrict the user to not use the same symbol again.

from django.db import models

class Watchlist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="watchlist")
    symbol = CharField(max_length=10, unique=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["user", "symbol"], name="user_symbol")
        ]

Upvotes: 0

Related Questions