user298519
user298519

Reputation: 1190

Django Twitter clone. How to restrict user from liking a tweet more than once?

I'm not sure where to start. Right now, the user can press like as many times they want and it'll just add up the total likes for that tweet.

models.py

class Howl(models.Model):
    author = models.ForeignKey(User, null=True)
    content = models.CharField(max_length=150)
    published_date = models.DateTimeField(default=timezone.now)
    like_count = models.IntegerField(default=0)
    rehowl_count = models.IntegerField(default=0)

    def get_absolute_url(self):
        return reverse('howl:index')

    def __str__(self):
        return self.content 

views.py

class HowlLike(UpdateView):
    model = Howl
    fields = []

    def form_valid(self, form):
        instance = form.save(commit=False)
        instance.like_count += 1
        instance.save()

        return redirect('howl:index')

Django Twitter clone. How to restrict user from liking a tweet more than once?

Upvotes: 1

Views: 156

Answers (3)

John Carter
John Carter

Reputation: 55271

As well as tracking how many Likes a post has, you'll probably also want to track who has "Liked" each post. You can solve both of these problems by creating a joining table Likes with a unique key on User and Howl.

The unique key will prevent any User from doing duplicate likes.

You can do this in Django with a ManyToManyField, note that since this means adding a second User relationship to Howl, we need to disambiguate the relationship by providing a related_name

Eg:

class Howl(models.Model):
    author = models.ForeignKey(User, null=True, related_name='howls_authored')
    liked_by = models.ManyToManyField(User, through='Like')

    # ...rest of class as above


class Like(models.Model):
    user = models.ForeignKey(User)
    howl = models.ForeignKey(Howl)

    class Meta:
      unique_together = (('user', 'howl'))

like_count count then becomes redundant, since you can use Howl.liked_by.count() instead.

The other benefit of this is that it allows you to store information about the Like - eg when it was added.

Upvotes: 1

user298519
user298519

Reputation: 1190

Changed liked_count in my models.py to

liked_by = models.ManyToManyField(User, related_name="likes")

views.py

class HowlLike(UpdateView):

    model = Howl
    fields = []

    def form_valid(self, form):
        instance = form.save(commit=False)
        instance.liked_by.add(self.request.user)

        instance.like_count = instance.liked_by.count()
        instance.save()

        return redirect('howl:index')

index.html

{{howl.liked_by.count}}

Upvotes: 0

Amin Etesamian
Amin Etesamian

Reputation: 3699

An idea could be adding a column to your table named likers and before incrementing like_counts check if the models.likers contains the new liker or not. If not increment the likes, if yes don't.

Upvotes: 0

Related Questions