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
相关产品推荐
相关产品推荐

