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

Django中基于一对一关联对象实现模糊搜索的报错解决

基于Django关联模型字段实现模糊搜索的问题解决

问题背景

我正在开发一个Django项目,已创建多个对象间的关联关系,整体运行正常,但模糊搜索(frazeSearch)功能出现问题。

模型代码

Student 模型(Students.py)

from django.db import models

from degreeCourse.models import DegreeCourse
from studentFinances.models import StudentFinances
from studentLoggingData.models import StudentLoggingData
from studentPersonalData.models import StudentPersonalData


# Create your models here.
# Part already after refactor
class Student(models.Model):
    personalStudentData = models.OneToOneField(
        StudentPersonalData,
        on_delete=models.CASCADE,
        default=None
    )
    loggingStudentData = models.OneToOneField(
        StudentLoggingData,
        on_delete=models.CASCADE,
        default=None
    )
    financesStudentData = models.ManyToManyField(
        StudentFinances
    )

    STUDENTS_UPLOAD_TO = "students/"
    image = models.ImageField(
        null=True,
        blank=True,
        upload_to=STUDENTS_UPLOAD_TO
    )


    def __str__(self):
        return f"{self.personalStudentData.name} {self.personalStudentData.surname}"

StudentPersonalData 模型(StudentPersonalData.py)

from django.db import models


# Create your models here.
class StudentPersonalData(models.Model):
    name = models.CharField(
        max_length=40,
        null=False,
        unique=False
    )
    surname = models.CharField(
        max_length=50,
        null=False,
        unique=False
    )
    personalIdNumber = models.CharField(
        max_length=11,
        null=False,
        unique=True
    )
    phoneNumber = models.CharField(
        max_length=20,
        null=False,
        unique=True
    )
    email = models.CharField(
        max_length=50,
        null=False,
        unique=True
    )
    streetAddress = models.CharField(
        max_length=40,
        null=True,
        unique=False
    )
    houseNumber = models.CharField(
        max_length=4,
        null=False,
        unique=False
    )
    flatNumber = models.CharField(
        max_length=4,
        null=True,
        unique=False
    )
    zipNumber = models.CharField(
        max_length=6,
        null=False,
        unique=False
    )
    country = models.CharField(
        max_length=40,
        null=False,
        unique=False
    )
    isActive = models.BooleanField(
        default=True,
        null=False
    )

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

错误的视图代码(Student的views.py)

def form_valid(self, form):
    query_set_filter = Q(
        Q(personalStudentData_name__icontains=form.cleaned_data["frazeSearch"])
        |Q(personalStudentData_surname__icontains=form.cleaned_data["frazeSearch"])
    )
    return render(
        request=self.request,
        template_name=self.template_name,
        context={
            "form": form,
            "students": Student.personalStudentData.objects.filter(query_set_filter)
        }
    )

触发的错误信息

AttributeError at /students/
'ForwardOneToOneDescriptor' object has no attribute 'objects'
Request Method: POST
Request URL:    http://127.0.0.1:8000/students/
Django Version: 4.1.7
Exception Type: AttributeError
Exception Value:    
'ForwardOneToOneDescriptor' object has no attribute 'objects'

解决方案

错误原因是你试图通过Student.personalStudentData.objects查询,这是错误用法——personalStudentData是Student模型的OneToOne字段,仅用于实例访问关联对象,不能作为类级别的查询入口调用.objects。

正确做法是在Student模型的QuerySet上,通过**双下划线(__)**跨关联模型查询字段:

修改后的form_valid方法:

def form_valid(self, form):
    search_query = form.cleaned_data["frazeSearch"]
    query_set_filter = Q(
        personalStudentData__name__icontains=search_query
    ) | Q(
        personalStudentData__surname__icontains=search_query
    )
    # 从Student模型出发过滤关联字段
    students = Student.objects.filter(query_set_filter)
    return render(
        request=self.request,
        template_name=self.template_name,
        context={
            "form": form,
            "students": students
        }
    )

关键说明

  • Django ORM支持用关联字段名__关联模型字段名的格式跨关联模型查询,比如personalStudentData__name表示Student关联的StudentPersonalData对象的name字段。
  • 必须从Student.objects构建查询,这是模型类的QuerySet入口,而非字段属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:54:54