如何在Django的用户个人页面展示用户收藏的商品
Django新手求助:如何获取用户收藏的商品列表
我是Django新手,正在搭建一个支持用户浏览、收藏商品的网站,希望用户登录后能在个人页面查看自己的收藏列表。目前已经创建了Products和Customers两个app,Products里的Product模型有一个likes多对多字段,点赞/取消点赞功能已经实现,但不知道怎么获取当前用户关联的所有收藏商品,求帮助。
现有代码
Product模型
class Product(models.Model): created_on = models.DateTimeField(auto_now_add=True) main_image = CloudinaryField('image', default='placeholder') item_name = models.CharField(max_length=50, unique=True) slug = models.SlugField(default="", null=False) price = models.DecimalField(max_digits=8, decimal_places=2) category = models.CharField(max_length=50) description = models.TextField(default='placeholder', blank=True, max_length=1000) colours = models.TextField(default='Ivory', blank=True, max_length=500) sizes_avail = models.TextField(default='Enquire in store', blank=True, max_length=500) likes = models.ManyToManyField(User, related_name='blog_post') def __str__(self): return self.item_name
Customer模型
class Customer(models.Model): user = models.OneToOneField(User, null=True, on_delete=models.CASCADE) profile_pic = CloudinaryField('image', default='placeholder') date_of_wedding = models.DateField(default='2024-12-31') website_url = models.CharField(max_length=500, null=True, blank=True) def __str__(self): return str(self.user) def get_absolute_url(self): return reverse('home')
点赞/取消点赞视图
def LikeView(request, pk): product = get_object_or_404(Product, id=request.POST.get('product_id')) liked = False if product.likes.filter(id=request.user.id).exists(): product.likes.remove(request.user) liked = False else: product.likes.add(request.user) liked = True return HttpResponseRedirect(reverse('product_details', args=[str(pk)]))
class ProductDetails(generic.DetailView): model = Product template_name = 'product_details.html' def get_context_data(self, *args, **kwargs): context = super(ProductDetails, self).get_context_data(*args, **kwargs) data = get_object_or_404(Product, id=self.kwargs['pk']) liked = False if data.likes.filter(id=self.request.user.id).exists(): liked = True context['liked'] = liked return context
商品点赞HTML代码
{% if user.is_authenticated %} <form action="{% url 'like_post' product.pk %}" method="POST"> {% csrf_token %} {% if liked %} <button type="submit", name="product_id", value="{{ product.id }}", class="btn btn-outline-primary btn-sm">Remove from Favourites</button> {% else %} <button type="submit", name="product_id", value="{{ product.id }}", class="btn btn-outline-danger btn-sm">Add to Favourites</button> {% endif %} </form> {% else %} <p><em><a href="{% url 'login' %}">Login</a> to save this dress to your Favourites</em></p> {% endif %}
解决方案
1. 优化关联名称(可选但推荐)
你的Product模型中likes字段的related_name是blog_post,和商品收藏的语义不符,建议改成更清晰的名称,比如favourite_products:
likes = models.ManyToManyField(User, related_name='favourite_products')
修改后记得运行python manage.py makemigrations和python manage.py migrate同步数据库。
2. 获取用户收藏的商品列表
在个人页面的视图中,直接通过当前登录用户的关联字段就能拿到收藏的商品:
函数式视图实现
from django.contrib.auth.decorators import login_required from Products.models import Product @login_required def user_favourites(request): # 通过用户的关联字段获取所有收藏商品 favourite_products = request.user.favourite_products.all() return render(request, 'customers/user_favourites.html', {'favourite_products': favourite_products})
类视图实现(用ListView)
from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import ListView from Products.models import Product class UserFavouritesView(LoginRequiredMixin, ListView): model = Product template_name = 'customers/user_favourites.html' context_object_name = 'favourite_products' def get_queryset(self): # 仅返回当前用户收藏的商品 return self.request.user.favourite_products.all()
3. 配置URL路由
在Customers app的urls.py中添加收藏页面的路由:
from django.urls import path from .views import user_favourites # 或者UserFavouritesView urlpatterns = [ # 其他已存在的URL... path('favourites/', user_favourites, name='user_favourites'), # 如果用类视图,替换成下面这行: # path('favourites/', UserFavouritesView.as_view(), name='user_favourites'), ]
4. 渲染收藏列表模板
创建customers/user_favourites.html模板,展示用户收藏的商品:
{% extends 'base.html' %} {% block content %} <h2>我的收藏商品</h2> {% if favourite_products %} <div class="row"> {% for product in favourite_products %} <div class="col-md-4 mb-4"> <div class="card"> <img src="{{ product.main_image.url }}" class="card-img-top" alt="{{ product.item_name }}"> <div class="card-body"> <h5 class="card-title">{{ product.item_name }}</h5> <p class="card-text">¥{{ product.price }}</p> <a href="{% url 'product_details' product.pk %}" class="btn btn-primary">查看详情</a> </div> </div> </div> {% endfor %} </div> {% else %} <p>你还没有收藏任何商品</p> {% endif %} {% endblock %}
内容的提问来源于stack exchange,提问作者llewellynksj
相关产品推荐
相关产品推荐

