You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django关联查询:筛选指定Listing与Bidder对应的Bid及Listing记录

需求与解决方案

模型定义

class User(AbstractUser):
    pass

class Listing(models.Model):
    name = models.CharField('Listing Name', max_length=64)
    description = models.TextField()
    owner = models.ForeignKey(User, related_name="listings", on_delete=models.CASCADE)
    active = models.BooleanField('Active', default=True)
    
class Bid(models.Model):
    listing = models.ForeignKey(Listing, related_name="listing_bids", on_delete=models.CASCADE)
    bidder =  models.ForeignKey(User,  related_name="user_bids", on_delete=models.CASCADE)
    amount = models.DecimalField(max_digits=7, decimal_places=2)

    class Meta:
        unique_together = ('listing', 'bidder',)

逻辑上,一个Listing可接收不同User的多个Bid,且通过unique_together约束,同一用户对同一Listing只能存在一条Bid记录。

需求

获取指定Listing(x)与指定User(y)对应的Listing行及关联的Bid行,要求仅返回一条Bid记录(若存在)或None,不通过手动循环实现。

解决方案

方法1:从Listing对象关联筛选

先获取目标Listing,再通过关联的listing_bids筛选指定用户的Bid:

# 假设已知listing的pk为x,user的pk为y
listing = Listing.objects.get(pk=x)
# 通过user实例筛选
bid = listing.listing_bids.filter(bidder__pk=y).first()
# 或者通过username筛选
bid = listing.listing_bids.filter(bidder__username="指定用户名").first()

first()方法会返回匹配的第一条记录(因唯一约束最多一条),无匹配则返回None。

方法2:直接从Bid模型查询(更高效)

直接查询Bid表,同时通过select_related一次性加载关联的Listing数据,避免二次数据库查询:

# 通过user实例和listing实例查询
bid = Bid.objects.filter(listing__pk=x, bidder__pk=y).select_related('listing').first()
# 或者通过username和listing pk查询
bid = Bid.objects.filter(listing__pk=x, bidder__username="指定用户名").select_related('listing').first()

若需单独获取Listing对象,可通过bid.listing直接访问。

方法3:使用get()方法(需处理异常)

如果需要明确判断记录是否存在,可使用get(),但需捕获不存在的异常:

from django.core.exceptions import ObjectDoesNotExist

try:
    bid = Bid.objects.get(listing__pk=x, bidder__pk=y)
except ObjectDoesNotExist:
    bid = None

这种方式适合必须确保记录存在的场景,否则用first()更简洁。

内容的提问来源于stack exchange,提问作者Wavesailor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:39:20