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

Django查询异常:QuerySet无email属性及MultipleObjectsReturned问题

问题描述

我需要获取系统内所有病理医生的列表,筛选条件为:用户的is_pathologist为True,且所属的Lab_Id等于请求数据中的request.data['email']。切换使用filter和get方法时,出现了Authentication.models.User.MultipleObjectsReturned错误(提示get()返回了12条User数据),同时还遇到QuerySet object has no attribute "email"的问题。


视图代码

@api_view(['POST'])
def getAllPathologists(request):
    user = get_user_model().objects.get(is_pathologist=True)
        # If user exists, get the employee
    print("user is: ", user)
    pathologist = Employee.objects.get(user=user.email, Lab_Id=request.data['email'])
    pathologistSerializer = EmployeeSerializer(pathologist, many=True)
    return Response(pathologistSerializer.data)

User模型代码

class User(AbstractUser):
    # Add additional fields here
    id = None
    email = models.EmailField(max_length=254, primary_key=True)
    name = models.CharField(max_length=100)
    password = models.CharField(max_length=100)
    contact_number = models.CharField(max_length=100)
    is_patient = models.BooleanField(default=False)
    is_doctor = models.BooleanField(default=False)
    is_homesampler = models.BooleanField(default=False)
    is_pathologist = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_lab = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now=True,editable=False)
    last_login = models.DateTimeField(auto_now=True)
    first_name = None
    last_name = None
    username = None

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'password']
    objects = CustomUserManager()

    def __str__(self):
        return self.email

    # Ensure that the password is hashed before saving it to the database
    def save(self, *args, **kwargs):
        self.password = make_password(self.password)
        super(User, self).save(*args, **kwargs)

    def has_perm(self, perm, obj=None):
        return self.is_superuser

Employee模型代码

class Employee(models.Model):
    user = models.OneToOneField(
        get_user_model(), on_delete=models.CASCADE, primary_key=True)
    CNIC = models.CharField(max_length=100, unique=True)
    Lab_Id = models.ForeignKey(Lab, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.name

EmployeeSerializer代码

class EmployeeSerializer(serializers.ModelSerializer):
    userData = UserSerializer(read_only=True, source='user')
    email = serializers.EmailField(write_only=True)
    password = serializers.CharField(write_only=True)
    name = serializers.CharField(write_only=True)
    contact_number = serializers.CharField(write_only=True)
    is_homesampler = serializers.BooleanField(write_only=True)

    class Meta:
        model = Employee
        # fields = " __all__"
        fields = ["CNIC", "Lab_Id", "userData",
                  "name", "contact_number", "email", "password", "is_homesampler"]

    def create(self, validated_data):
        print("validated data = ", validated_data)
        email = validated_data.pop("email")
        password = validated_data.pop("password")
        name = validated_data.pop("name")
        contact_number = validated_data.pop("contact_number")
        is_homesampler = validated_data.pop("is_homesampler")
        user = get_user_model().objects.create_user(
            email=email, password=password, name=name, contact_number=contact_number)
        if (is_homesampler):
            user.is_homesampler = True
        else:
            user.is_pathologist = True
        user.save()

        EmployeeObj = Employee.objects.create(user=user, **validated_data)
        return EmployeeObj

错误原因及修复方案

  1. MultipleObjectsReturned错误:
    get()方法要求返回唯一对象,但系统中存在多个is_pathologist=True的用户,因此必须用filter()获取符合条件的对象集合(QuerySet)。

  2. QuerySet object has no attribute "email"问题:
    QuerySet是对象集合,不能直接访问单个对象的属性。另外,Employee模型的user字段是OneToOne关联,查询时应关联User实例,而非用user=user.email(该字段存储的是User对象,不是字符串)。

  3. 逻辑优化:
    直接从Employee模型出发,通过关联查询筛选符合条件的病理医生,无需单独查询User模型。

修复后的视图代码:

@api_view(['POST'])
def getAllPathologists(request):
    # 关联筛选:Employee对应的User是病理医生,且所属Lab匹配请求的email
    # 注意:若Lab模型的主键是email,用Lab_Id=request.data['email'];若Lab有单独email字段,用Lab_Id__email=request.data['email']
    pathologists = Employee.objects.filter(
        user__is_pathologist=True,
        Lab_Id__email=request.data['email']
    )
    # 序列化多个对象必须指定many=True
    pathologistSerializer = EmployeeSerializer(pathologists, many=True)
    return Response(pathologistSerializer.data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:48:04