Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Like Button

Tags:

django

I'm been trying to create a like button for my pet pictures in each board for my app but I can't figure out how to create one because it contain Integer .Usually I have an idea and understanding of the functions I create.

When the user clicks on the like button . The like button will increase by 1 and it will display near the picture.

This is my picture module.

class Picture(models.Model):
    user = models.ForeignKey(User)
    board = models.ForeignKey(Board ,related_name='lo')
    image = models.FileField(upload_to="images/",blank=True,null=True)
    description = models.TextField()
    is_primary = models.BooleanField(default=False)

    def __unicode__(self):
        return self.description

Can someone please help me create the basics of a like button? So I can understand the logic of the function.

like image 294
donkeyboy72 Avatar asked Mar 14 '13 11:03

donkeyboy72


People also ask

How do you code like buttons?

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> </head>

How do I make likes and dislikes in Django?

1= like. 2=dislike. The fourth field, just to have more meta data, is the date field, to know when the user liked or disliked the post. Just to make likes or dislikes more readable in the Django admin, I use the __str__ function to show the user, post, and value, instead of just Preference objects.


2 Answers

I assume that many users can like many pictures.

You'll need another model:

class Like(models.Model):
    user = models.ForeignKey(User)
    picture = models.ForeignKey(Picture)
    created = models.DateTimeField(auto_now_add=True)

And call the number of likes like this:

p = Picture.objects.get(...)
number_of_likes = p.like_set.all().count()

To increase the number of likes you might want to do something like that in a view:

def like(request, picture_id):
    new_like, created = Like.objects.get_or_create(user=request.user, picture_id=picture_id)
    if not created:
        # the user already liked this picture before
    else:
        # oll korrekt

so whenever someone clicks on the same like button twice, he only counts as one.

To find out if the current user already likes the displayed image or not:

def picture_detail(request, id):
    pic = get_object_or_404(Picture, pk=id)
    user_likes_this = pic.like_set.filter(user=request.user) and True or False

Hope this helps.

like image 56
mawimawi Avatar answered Oct 24 '22 18:10

mawimawi


I am gonna share my like button app experience with you

first create like app and inside the like.models establish

from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class LikeModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    liked = models.BooleanField()
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    timestamp = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return str(self.user.username)

then you should have ajax app which we will execute save commands just one click on heart or thumb or whatever you want, Once you create the ajax app then dont change anything in models just adjsut urls and get inside the ajax.views and establish codes

def like_it(request):
    user = request.user
    if request.method == 'POST':
        ObjectId = int(request.POST['objectid'])
        Tip = str(request.POST['contentType'])

        likes = LikeModel.objects.filter(object_id=ObjectId, content_object=Tip) # in here we filtered the particular post with its id
        if likes: # if the particular post is there
            if str(user) in str(likes): # then we check the user which is us, in there
                like_obj = LikeModel.objects.get(user=user,object_id=ObjectId, content_object=Tip) #if we there and we returned this data, this part for saving data, I mean if this data is already created than we dont have to delete and create again, we just change LikeModel.liked true or false state, so that if you create like and it will never delete, it just change liked or like state
            else:
                pass

        if Tip == 'UserPost':
            post_content_type_by = UserPost.objects.all().first()

            if str(user) not in str(likes):
                like = LikeModel.objects.create(user=user, liked=True, content_object=ContentType.objects.get_for_model(Tip), object_id=ObjectId)
                like.save() # if data is created then we say 'new'
                okey = 'new'

            elif str(user) in str(likes) and like_obj.liked:
                like_obj.liked = False
                like_obj.save() # if data is already there, then we save it False
                okey = 'false'

            elif str(user) in str(likes) and like_obj.liked == False:
                like_obj.liked = True
                like_obj.save() # if data is already changed to False and we save again to True
                okey = 'true'


    return render(request,'ajaxlike.html',{'likes':likes,'okey':okey})

and right after that we gonna create our ajax templates for returning and saving ajax datas, I just call it like.html

  {% if okey == 'new' %}
    new
  {% elif okey == 'false' %}
    false
  {% elif okey == 'true' %}
    true
  {% endif %}

now create your index html or wherever you want to establish like buttons, and write the jquery codes

  $('.thumb').click(function(){
    var indx = $('.thumb').index(this)
    var ObjectId = $('.ObjectId:eq('+indx+')').text()
    $.ajax({
      type: 'POST',
      url: '/ajax/ajaxlike/',
      data: {
        'contentType':'UserPost',
        'objectid':ObjectId,
        'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
      },
      success: LikePost,
      dataType: 'html'
    });

    function LikePost(data, textStatus, jqXHR){
      if($.trim(data) == 'new'){
        $('.thumb:eq('+indx+')').css('color','#FF0033');
      }else if($.trim(data) == 'false'){
        $('.thumb:eq('+indx+')').css('color','');

      }else if($.trim(data) == 'true'){
        $('.thumb:eq('+indx+')').css('color','#FF0033');

      }
    }
  });

above the example when we click the thumb and it saves the datas in LikeModel then from like.html which is returning ajax datas, if data is new and it colored the thumb to red, if data is false which mean is this data is already saved but now you want to delete like, so then thumb colored back to normal color, and if data is true which mean is you already created like data for this post but then you delete your thumb but now you want to like again so than thumb goes red again

okay this is almost done but remember that when the page refreshes all colored thumbs and counted likers not shown in the page, so it is so simple just write some little codes and it will load everything again

so what we did here, we created like apps and inside the like table at the database, after a data is created by user then it will never delete by user, it is just changed to the liked true or false state by a boolean field so that as an admin you always gonna keep all data that could be useful for us,but the tricky part is, all events are handled by javascript so you have to pay attention while writing codes with jquery, for example make sure the ajax are working well, and I want to mention this too, if in your page for example firstly you load just for 10 post and then scrolling page and page is automatically load the other 10 post and like that then the like buttons not gonna work because your main jquery codes in the page not gonna work in loaded div, so I mean you have to make some additional thing for this,

But the main Idea that I wanted to share my custom like and ajax apps, It worked for me and this one is never failed version for me :D, sincerely

like image 31
Ozan Honamlioglu Avatar answered Oct 24 '22 18:10

Ozan Honamlioglu