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

如何查询含ForeignKey与OneToOneField的Django模型以获取登录嘉宾用户注册的活动名称

解决Django查询登录嘉宾已注册活动名称的问题

首先,你的模型关联存在一个核心问题——Guest和Pin之间没有建立正确的数据库关联,这导致你没法通过当前用户追踪到对应的活动。我们先修正模型结构,再编写正确的查询逻辑。

第一步:修正模型关联与错误

1. 修复Guest模型的Pin关联

当前Guest模型里的pin是字符串字段,无法和Pin模型建立关联。我们需要把它改成外键,这样才能通过Guest找到对应的Pin,进而关联到Ticket和Event:

class Guest(models.Model):
    guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
    # 替换原CharField为ForeignKey,关联Pin模型
    pin = models.ForeignKey(
        Pin, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True, 
        related_name="registered_guests"  # 反向关联名,方便从Pin找Guest
    )
    
    def __str__(self):
        return f"{self.guest_name}"

2. 修复Pin模型的save方法错误

Pin模型的save方法里有个语法错误(用了==比较而非=赋值),导致reference字段无法正确生成,修正如下:

class Pin(models.Model):
    # ... 其他字段保持不变 ...
    def save(self, *args, **kwargs):
        # 仅当reference未设置时生成(因为已经设置了default=uuid.uuid4,这步可选,但更严谨)
        if not self.reference:
            self.reference = uuid.uuid4()
        super().save(*args, **kwargs)

第二步:编写正确的查询逻辑

当用户登录后,我们可以通过request.user找到对应的Guest实例,再通过关联链Guest -> Pin -> Ticket -> Event获取用户已注册的活动。

视图中的实现示例

from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .models import Event, Guest

@login_required
def user_registered_events(request):
    # 获取当前登录用户对应的Guest对象
    try:
        current_guest = Guest.objects.get(guest_name=request.user)
    except Guest.DoesNotExist:
        # 如果用户还没有创建Guest记录,返回空列表
        event_names = []
    else:
        # 通过关联链查询用户已注册的活动,distinct()避免重复(同一个活动可能对应多个Pin)
        registered_events = Event.objects.filter(
            ticket__pin__registered_guests=current_guest
        ).distinct()
        # 提取活动名称列表
        event_names = [event.event_name for event in registered_events]
    
    return render(request, 'your_template.html', {'registered_event_names': event_names})

直接获取活动名称的QuerySet写法

如果你只需要活动名称字符串,可以用values_list简化:

event_names = Event.objects.filter(
    ticket__pin__registered_guests=current_guest
).values_list('event_name', flat=True).distinct()

为什么你之前的查询失败?

你之前尝试的Pin.objects.filter(guest__guest_name__icontains=request.user)有两个问题:

  1. 关联不存在:Guest和Pin没有外键关联,guest__guest_name这个查询路径根本不成立;
  2. 匹配方式错误:guest_name是OneToOne关联的User对象,用icontains(字符串包含匹配)完全不适用,应该用精确匹配guest__guest_name=request.user,但前提是模型关联正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:38:14