Reputation: 1781
I have a model:
class Product(models.Model):
title = models.CharField(max_length=200)
url = models.URLField()
pub_date = models.DateTimeField()
votes_total = models.IntegerField(default=1)
image = models.ImageField(upload_to='images/')
icon = models.ImageField(upload_to='images/')
body = models.TextField()
hunter = models.ForeignKey(User, on_delete=models.CASCADE)
Now I'd like to add a functionality of upvoters to know on what products user has already voted. I need this to allow users vote on the one product only once.
Again, to clarify - user can vote on several products but only once on each.
So the relation is one product - many users (upvoters).
I tried to add the next field but cannot make a migration even if default field is provided. Also I tried to clear the database but again cannot make it work.
upvoters = models.ForeignKey(User, on_delete=models.CASCADE, related_name='upvoted')
I suppose it works the next way:
Field to determine upvoted products. To check if user has been upvoted on product, call:
User.upvoted.filter(id=product.id).count() == 1
This means that user has already upvoted on this product.
What's wrong? What should I change to make it work?
Upvotes: 0
Views: 108
Reputation: 653
You will have to use ManyToMany, but you can use a custom through model to restrict the product/vote combinations.
To Product class, add:
voters = models.ManyToManyField(User, through='ProductVote', related_name='product_voters')
Then add the custom through model:
class ProductVote(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Vote, on_delete=models.CASCADE)
class Meta:
unique_together = ['user', 'product']
If you try to add a vote for the same user/product combination, an IntegrityError will be raised.
Upvotes: 4