如何在Django中实现关联查询?附用户与市场订阅模型
嘿,针对你定义的这三个Django模型,关联查询其实非常简单,Django ORM已经帮我们做好了大部分封装,我给你梳理几个常见的查询场景和用法:
1. 从用户(User)出发,查询他订阅的所有市场
因为一个用户可以有多个订阅记录(User -> 多UserMarketSubscription),Django会自动给User模型生成一个反向关联属性,默认名为usermarketsubscription_set。你可以用它直接获取这个用户的所有订阅:
# 先获取目标用户 target_user = User.objects.get(id=1) # 获取该用户的所有订阅记录 user_subscriptions = target_user.usermarketsubscription_set.all()
如果想直接拿到订阅的Market对象,推荐用select_related来避免N+1查询(一次性加载关联数据,提升性能):
# 同时加载关联的Market数据 subscriptions_with_market = target_user.usermarketsubscription_set.select_related('market').all() # 提取所有Market对象 subscribed_markets = [sub.market for sub in subscriptions_with_market]
2. 从市场(Market)出发,查询所有订阅它的用户
和上面的逻辑类似,Market模型也有默认的反向关联属性usermarketsubscription_set,用来获取所有订阅该市场的记录:
# 先获取目标市场 target_market = Market.objects.get(name='美股') # 获取所有订阅该市场的记录,同时加载关联的User数据 subscriber_records = target_market.usermarketsubscription_set.select_related('user').all() # 提取所有订阅用户 subscribed_users = [rec.user for rec in subscriber_records]
3. 直接通过中间表(UserMarketSubscription)进行条件查询
如果需要基于订阅日期(date_in/date_out)做过滤,或者同时筛选用户和市场的组合,直接查询中间表会更灵活:
from datetime import date, timedelta # 示例:查询近30天内新订阅的记录,同时加载关联的用户和市场 recent_subs = UserMarketSubscription.objects.filter( date_in__gte=date.today() - timedelta(days=30) ).select_related('user', 'market') # 示例:查询用户ID为1的用户订阅"A股"的记录 user_a_stock_sub = UserMarketSubscription.objects.filter( user_id=1, market__name='A股' ).first()
默认的反向关联名字(比如usermarketsubscription_set)有点冗长,你可以在定义ForeignKey时加上related_name,让代码更易读:
class UserMarketSubscription(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='subscriptions') market = models.ForeignKey('Market', on_delete=models.CASCADE, related_name='subscribers') date_in = models.DateField(default=year_back) date_out = models.DateField(default=year_back)
修改后,查询代码就可以变得更直观:
# 获取用户的所有订阅 target_user.subscriptions.all() # 获取市场的所有订阅用户 target_market.subscribers.all()
内容的提问来源于stack exchange,提问作者Валерий Герасимов
相关产品推荐
相关产品推荐

