Django多对多字段查询:实现用户关注企业的产品推送功能
Django QuerySet实现关注企业的产品时间线方案
嘿,我完全理解你想要找个最简单的方案,不想折腾那些复杂的第三方库——毕竟Django原生的QuerySet就足够解决这个问题了!先帮你梳理下思路,顺便修正下模型里的小问题,因为基础对了后续才好搞。
第一步:修正模型中的基础问题
你给出的模型里有几个小错误,先调整下,不然运行会报错:
CharField必须指定max_length参数,不能传models.Model- 外键关联用户模型时,要引用正确的
User类(比如从django.contrib.auth.models导入) related_name的命名要更清晰,方便后续反向查询
修正后的模型代码:
from django.contrib.auth.models import User from django.db import models class Company(models.Model): name = models.CharField(max_length=255) # 这里的user字段应该是企业的拥有者?unique=True限制一个用户只能拥有一家企业 user = models.ForeignKey( User, unique=True, null=True, related_name="owned_companies", on_delete=models.SET_NULL ) # 多对多字段:用户关注企业,related_name用来反向获取用户关注的所有企业 follow = models.ManyToManyField( User, related_name="followed_companies", blank=True ) class Product(models.Model): name = models.CharField(max_length=255) company = models.ForeignKey( Company, related_name="products", null=True, on_delete=models.SET_NULL ) # 新增创建时间字段,用来按时间排序时间线 created_at = models.DateTimeField(auto_now_add=True)
第二步:用QuerySet实现时间线逻辑
在视图里,我们只需要利用Django的反向查询和__in过滤,就能轻松拿到当前用户关注企业的所有产品,完全不需要第三方库:
from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from .models import Product @login_required # 确保只有登录用户能访问时间线 def Display(request): # 1. 获取当前用户关注的所有企业(通过related_name反向查询) followed_companies = request.user.followed_companies.all() # 2. 过滤出这些企业发布的所有产品,按发布时间倒序排列(最新的在前) timeline_products = Product.objects.filter( company__in=followed_companies ).order_by('-created_at') # 如果你想把用户自己企业的产品也加入时间线,可以用Q对象做或查询: # from django.db.models import Q # own_companies = request.user.owned_companies.all() # timeline_products = Product.objects.filter( # Q(company__in=followed_companies) | Q(company__in=own_companies) # ).order_by('-created_at').distinct() return render(request, 'timeline.html', { 'timeline_products': timeline_products })
第三步:模板中展示时间线
在模板里循环渲染产品即可,示例如下:
<!-- timeline.html --> <h2>我的产品时间线</h2> {% for product in timeline_products %} <div class="product-card"> <h3>{{ product.name }}</h3> <p>发布企业:{{ product.company.name }}</p> <p>发布时间:{{ product.created_at|date:"Y-m-d H:i" }}</p> </div> {% empty %} <p>还没有关注企业发布的产品,快去关注几家企业吧!</p> {% endfor %}
为什么这个方案最简单?
- 完全基于Django原生QuerySet,不需要引入任何第三方库,学习和维护成本极低
- 所有过滤逻辑都在数据库层面完成,性能远高于在内存中循环处理
- 代码简洁清晰,后续扩展(比如加入产品分类、过滤条件)也很方便
内容的提问来源于stack exchange,提问作者ebong
相关产品推荐
相关产品推荐

