Saya membangun fungsionalitas "suka" posting di halaman daftar posting (di mana posting dari satu pengguna ditampilkan). Menggunakan contoh dari buku "Django dengan contoh", saya melakukan ajax seperti tombol di bawah setiap posting. Tapi itu bekerja dengan tidak benar. Dalam contoh itu tombol suka dibuat untuk satu halaman posting, dan saya mencoba menyesuaikannya untuk halaman daftar posting (banyak posting dalam satu halaman). Ketika menekan tombol suka di database semuanya baik-baik saja - saya mendapat plus satu suka untuk posting tertentu. Tetapi di ujung depan hal-hal aneh terjadi - jumlah suka untuk semua posting berubah, seolah-olah semua posting terhubung. Dan ketika saya melakukan Suka dan tidak suka, jumlah suka untuk semua pos berubah menjadi beberapa nilai besar. Saya pikir itu terjadi karena dalam hal ini Ajax menggunakan pemilih kelas yang sama (bukan id) untuk semua posting. Saya masih tidak begitu baik di Django dan Ajax dan tidak dapat menemukan cara untuk membuat ini bekerja dengan benar. Menghabiskan waktu lama untuk mencoba memperbaikinya dan mencari di Google tanpa hasil. Bantuan apa pun dihargai.

Di bawah ini adalah kodenya.

Model pos dengan bidang suka:

class Posts(models.Model):
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True, blank=True)
    content = models.TextField()
    image = models.ImageField(upload_to="posts/%Y/%m/%d", null=True,blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                        related_name='images_liked',
                                        blank=True)
    total_likes = models.PositiveIntegerField(db_index=True,
                                              default=0)

    def __str__(self):
        return self.title

     
    def get_absolute_url(self):
        return reverse("post_detail", kwargs={"slug": self.slug})


def slug_generator(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)


pre_save.connect(slug_generator, sender=Posts)

Fungsi post_like di view.py pengguna:

@ajax_required
@login_required
@require_POST
def post_like(request):
    post_id = request.POST.get('id')
    action = request.POST.get('action')
    if post_id and action:
        try:
            post = Posts.objects.get(id=post_id)
            if action == 'like':
                post.users_like.add(request.user)
                create_action(request.user, 'likes', post)
            else:
                post.users_like.remove(request.user)
            return JsonResponse({'status':'ok'})
        except:
            pass
    return JsonResponse({'status':'ok'})

Kode di urls.py untuk ini:

urlpatterns = [
    
    path('like/', views.post_like, name='like'),
...another urls...
]

html untuk tombol suka dan menghitung suka:

{% with total_likes=post.users_like.count users_like=post.users_like.all %}
    <div class="image-info">
      <div>
        <span class="count">
         <span class="total">{{ total_likes }}</span>
         like{{ total_likes|pluralize }}
        </span>
        
        <a href="#" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
          {% if request.user not in users_like %}
            Like
          {% else %}
            Unlike
          {% endif %}
        </a>
      </div>
      
    </div>
    <div class="image-likes">
     
     
    </div>
  {% endwith %}

Dan dalam file html yang sama, di mana tombol berada, di bawahnya ada kode ajax untuk fungsi suka:

{% block domready %}
$('a.like').click(function(e){
    e.preventDefault();
    
    $.post('/like/',
      {
        id: $(this).data('id'),
        action: $(this).data('action')
      },
      function(data){
        if (data['status'] == 'ok')
        {
          var previous_action = $('a.like').data('action');

          // toggle data-action
          $('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
          // toggle link text
          $('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');

          // update total likes
          var previous_likes = parseInt($('span.count .total').text());
          $('span.count .total').text(previous_action == 'like' ? previous_likes + 2 : previous_likes - 2);
          
        }
      }
    );
    
  });
{% endblock %}
0
Boris 10 Juli 2020, 14:46

1 menjawab

Jawaban Terbaik

Anda hanya perlu mengubah tombol suka yang telah diklik dengan memasukkannya ke dalam fungsi click Anda. Anda dapat sedikit merapikan kode Anda, tetapi agar tetap serupa, Anda dapat melakukan sesuatu seperti:

$('a.like').click(function(e){
    e.preventDefault();
    // Get the clicked button.
    const $clickedButton = $( this );
    
    $.post('/like/',
        {
            id: $clickedButton.data('id'),
            action: $clickedButton.data('action')
        }, 
        function(data) {
            if (data['status'] == 'ok') {
                // Update the clicked button only.
                var previous_action = $clickedButton.data('action');
                
                // toggle data-action
                $clickedButton.data('action', previous_action == 'like' ? 'unlike' : 'like');
                // toggle link text
                $clickedButton.text(previous_action == 'like' ? 'Unlike' : 'Like');

                // update total likes
                const $total = $clickedButton.prev('span.count').children('.total');
                var previous_likes = parseInt($total.text());
                $total.text(previous_action == 'like' ? previous_likes + 2 : previous_likes - 2);
            }
        }
    );
});

Saya tidak 100% yakin mengapa Anda menambahkan/mengurangi 2 dari total daripada 1, tetapi saya tidak memiliki konteks yang cukup.

1
alstr 10 Juli 2020, 12:11