如何在事件发生后使页面重定向到同一页面

2024-10-02 16:23:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在我的网站上实现向上投票和向下投票功能。然而,有一个我不喜欢的特殊行为,即每当用户单击按钮时,他不应该被重定向到另一个页面,而是应该保持在同一页面上

单击upvote按钮后发生的情况是,它会转到我不想要的urlhttp://localhost:8001/upvote/2/。我希望它保持在同一页上,即http://localhost:8001/view-supplier/

models.py

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)

    # CUSTOM USER FIELDS
    firstname = models.CharField(max_length=30)
    lastname = models.CharField(max_length=30)
    upvotes = models.IntegerField(default=0)
    downvotes = models.IntegerField(default=0)
    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)
        
    def get_email(self):
        return self.email

views.py

def Viewsupplier(request):
    title = "All Suppliers"
    suppliers = User.objects.filter(user_type__is_supplier=True)

    context = {"suppliers":suppliers, "title":title}

    return render(request, 'core/view-suppliers.html', context)

@login_required
def upvote(request, pk):
    supplier_vote = get_object_or_404(User, id=pk)
    supplier_vote.upvotes += 1
    supplier_vote.save()
    upvote_count = supplier_vote.upvotes
    context = {"supplier_vote":supplier_vote, "upvote_count":upvote_count}
    return render(request, "core/view-suppliers.html", context)

@login_required
def downvote(request, pk):
    supplier_vote = get_object_or_404(User, id=pk)
    supplier_vote.downvotes -= 1
    supplier_vote.save()
    downvote_count = supplier_vote.downvotes
    context = {"supplier_vote":supplier_vote, "downvote_count":downvote_count}
    return render(request, "core/view-suppliers.html", context)

url.py

from django.urls import path
from . import views

urlpatterns = [
    path('upvote/<int:pk>/', views.upvote, name='upvote'),
    path('downvote/<int:pk>/', views.downvote, name='downvote'),
]

view-supplier.html

<table class="table table-borderless table-data3">
    <thead>
        <tr>
            <th>No</th>
            <th>Country</th>
            <th>Votes</th>
        </tr>
    </thead>
    <tbody>
        {% for supplier in suppliers %}
        <tr>
            <td>{{forloop.counter}}</td>
            <td>{{supplier.country}}</td>
            <td>
                <div class="table-data-feature">
                    <a href="{% url 'upvote' supplier.id %}" class="m-r-10">
                        <button class="item" data-toggle="tooltip" data-placement="top" title="Like">
                        <i class="zmdi zmdi-thumb-up"></i>{{upvote_count}}</button>
                    </a>
                    <a href="{% url 'downvote' supplier.id %}">
                        <button class="item" data-toggle="tooltip" data-placement="top" title="Dislike">
                        <i class="zmdi zmdi-thumb-down"></i>{{downvote_count}}</button>
                    </a>
                </div>
            </td>
        </tr>
        {% empty %}
            <tr><td class="text-center p-5" colspan="7"><h4>No supplier available</h4></td></tr>
        {% endfor %}
    </tbody>
</table>

Tags: modelsrequestcountcontexttabletrclasstd
3条回答

您需要实现一个API(应用程序编程接口)来异步发送upvote和downvoteDjango REST framework是创建自己的API的方法。你可以在YouTube上观看数小时关于这个主题的视频教程。Django REST框架的文档非常棒,而且易于阅读。Django是一个服务器端web框架,这意味着只有当您提交到服务器时,它才能帮助您。您完全可以重新加载同一页面:

return HttpResponseRedirect(reverse('<app_name>:<url_name>'))

但是,会有一个中断。因此,处理此类行为的推荐方法是使用JavaScript的API(如Fetch API)对REST框架进行异步调用

如果出于对学习异步编码的错误恐惧,您决定以旧的方式向服务器发送数据,则始终可以使用向上投票和向下投票来提交用户数据并更新计数。然后,在视图中,需要获取更新的视图计数并将其传递给上下文。因此,您的upvote视图会更改upvote计数并触发Viewsupplier视图。然后,在ViewSupplier视图中,获取计数并将其添加到上下文中

# in your template
<a href="{% url 'upvote' supplier.id %}" class="m-r-10">
   <button class="item" data-toggle="tooltip" data-placement="top" title="Like">
   <i class="zmdi zmdi-thumb-up"></i>{{upvote_count}}</button>
</a>

# in your view
def Viewsupplier(request):
    title = "All Suppliers"
    suppliers = User.objects.filter(user_type__is_supplier=True)

    # Get the updated count:
    suppliers_votes_count = {}
    for supplier in suppliers:
        upvote_count    = supplier.upvotes
        downvote_count  = supplier.upvotes

        supplier_count = {supplier: {'upvote': upvote_count, 'downvote': downvote_count } }
    
    suppliers_votes_count.update(supplier_count)

    context = {"suppliers":suppliers, "title":title, "suppliers_votes_count": suppliers_votes_count }

    return render(request, 'core/view-suppliers.html', context)

@login_required
def upvote(request, pk):
    supplier_vote = get_object_or_404(User, id=pk)
    supplier_vote.upvotes += 1
    supplier_vote.save()
    upvote_count = supplier_vote.upvotes
    context = {"supplier_vote":supplier_vote, "upvote_count":upvote_count}
    return HttpResponseRedirect(reverse('core:view_supplier'))

以下是我将如何实现这一目标:

首先,我有一些简单的表格来处理上升票/下降票:

<form method="POST" action="{% url 'view-supplier' %}"> //upvote form
  {% csrf_token %}
  <input type="hidden" name="upvote-button">
  <button type="submit" style="width:100%">Upvote Button</button>
</form>

<form method="POST" action="{% url 'view-supplier' %}"> // downvote form
  {% csrf_token %}
  <input type="hidden" name="downvote-button">
  <button type="submit" style="width:100%">Downvote Button</button>
</form>

然后我将视图设置为:

def supplierView(request):
   supplier_vote = get_object_or_404(User, id=pk)

   if 'upvote-button' in request.POST:
         supplier_vote.upvotes += 1
         supplier_vote.save()
         upvote_count = supplier_vote.upvotes

   elif 'downvote-button' in request.POST:
         supplier_vote.downvotes -= 1
         supplier_vote.save()
         downvote_count = supplier_vote.downvotes
   
   else:
         downvote_count = supplier_vote.downvotes
         upvote_count = supplier_vote.upvotes

   context = {
    'upvote_count': upvote_count,
    'downvote_count': upvote_count,
   }

   return render(request, 'main/view-suppliers.html', context)

这样,当有人单击upvote按钮时,他们将被重定向到同一视图,该视图将处理添加upvote并更新上下文

如果view-supplier是一个详细视图,那么还必须将PK传递给该视图

这可以通过使用AJAX轻松实现

与其将supplier_id作为URL的一部分提供,不如将AJAX中的supplier_id发送到Django Upvote视图。你可以这样做

HTML:

<button id="{{ supplier_id }}" class="item upvote" data-toggle="tooltip" data-placement="top" title="Like">
<i class="zmdi zmdi-thumb-up"></i>{{upvote_count}}
</button>

使用Javascript从单击按钮事件中提取supplier_id

JavaScript:

$('.upvote').on('click', function () {
var supp_id = $(this).attr('id');
  $ajax({
    type: 'POST',
    url: '/upvote/',
    data: {
       supplier_id: supplier_id,
    },
   success: function (data) {
   if (data.status == 'success') {
       /* Your upvote logic like updating the color of button or showing Unlike etc.,*/
    }
  }
 });
});

将Djangourl.py中的url模式更改为

urlpatterns = [path('upvote/', views.upvote, name='upvote'),

视图.py

def upvote(request):
    if request.method == 'POST':
        supplier_id = request.POST['supplier_id']
        # Your DB update logic goes here....
        return JsonResponse({'status': 'success'})
    else:
        return JsonResponse({'status': 'Error'})

同样,您也可以对downvote执行相同的操作

相关问题 更多 >