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

Django多表(Event/Ticket/Pin)按活动名搜索报错求助

Django关联模型搜索报错:Field 'id' expected a number but got 'Birth Day'

问题背景

我有三个通过ForeignKey关联的Django模型(Event、Ticket、Pin),想要通过**活动名称(Event name)**搜索并展示关联的Pin详情,但运行代码时报错:Field 'id' expected a number but got 'Birth Day'。

模型代码

class Event(models.Model):
    event_name = models.CharField(max_length=100)
    date = models.DateField(auto_now_add=False, auto_now=False, null=False)
    event_venue = models.CharField(max_length=200)
    event_logo = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images')
    added_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.event_name}"

    def get_absolute_url(self):
        return reverse("event_detail", args=[str(self.id)])

class Ticket(models.Model):
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    price = models.PositiveIntegerField()
    category = models.CharField(max_length=100, choices=PASS, default=None, blank=True, null=True)
    added_date = models.DateField(auto_now_add=True)

    def __str__(self):
        return f"{self.event} "

    def get_absolute_url(self):
        return reverse("ticket-detail", args=[str(self.id)])

    def generate_pin():
        return ''.join(str(randint(0, 9)) for _ in range(6))

class Pin(models.Model):
    ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
    value = models.CharField(max_length=6, default=generate_pin, blank=True)
    added = models.DateTimeField(auto_now_add=True,  blank=False)
    reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
    status = models.CharField(max_length=30, default='Not Activated')

    def save(self, *args, **kwargs):
        self.reference == str(uuid.uuid4())
        super().save(*args, **kwargs) 

    def __unicode__(self):
        return self.ticket

    class Meta:
        unique_together = ["ticket", "value"]

    def __str__(self):
        return f"{self.ticket}"

    def get_absolute_url(self):
        return reverse("pin-detail", args=[str(self.id)])

视图代码

def Pin_Search_List(request):
    context = {}
    #Search PIN Form
    searchForm = SearchEventTicketForm(request.GET or None)

    if searchForm.is_valid():
        #Value of search form
        value = searchForm.cleaned_data['value']
        #Filter PIN by Events using Q Objects
        #event_filter = Q(ticket__event_icontains = value) 
        #Apply the Profile Object Filter
        list_pins = Pin.objects.filter(ticket__event=value) 
       
    else:
        list_pins = Pin.objects.all()

    page_title = "Search and Print PINs"
    context.update ({
        'page_title':page_title,
        'list_pins':list_pins,
        'searchForm':searchForm,
    })
    return render(request, 'user/pin_list.html', context)

错误原因

报错核心是Pin.objects.filter(ticket__event=value)这行代码:

  • ticket__event指向的是Event模型的外键ID(Django外键默认存储关联模型的主键值)
  • 传入的value是活动名称字符串(比如"Birth Day"),Django尝试将字符串转换为数字ID,因此抛出类型不匹配的错误。

解决方案

需要通过Event模型的event_name字段进行过滤,而不是直接匹配外键ID,提供两种实现方式:

方案1:跨关联模型直接查询字段

修改视图中的过滤逻辑,使用双下划线跨模型访问字段:

list_pins = Pin.objects.filter(ticket__event__event_name__icontains=value)
  • ticket__event__event_name:通过Ticket关联到Event,再访问Event的event_name字段
  • __icontains:实现不区分大小写的模糊匹配,若需要精确匹配可替换为__exact

方案2:先匹配Event再关联查询

如果需要更清晰的逻辑,可先查询符合条件的Event对象,再关联查询Pin:

matched_events = Event.objects.filter(event_name__icontains=value)
list_pins = Pin.objects.filter(ticket__event__in=matched_events)

额外优化提示

Pin模型的save方法存在笔误:self.reference == str(uuid.uuid4())是比较运算符,应改为赋值运算符=,否则不会修改reference字段:

def save(self, *args, **kwargs):
    self.reference = str(uuid.uuid4())
    super().save(*args, **kwargs) 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:10:32