首页 > 解决方案 > 具有自定义属性的 Django 查询集

问题描述

django==3.0.5 django-filter==2.3.0 djongo==1.3.3 我的数据库是 mongodb 我有一个简单的模型,如下所示

class Parishioner(models.Model):

    def _age(self):
        return date.today().year - self.dob.year

    """Parishioner model"""
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    dob = models.DateField()
    age = property(_age)
    GENDER_CHOICES = [("Male", "Male"), ("Female", "Female"), ("Other", "Other")]
    gender = models.CharField(max_length=10, choices=GENDER_CHOICES)
    address = models.CharField(max_length=1000)
    fathers_name = models.CharField(max_length=500)
    mothers_name = models.CharField(max_length=500)
    baptism_certificate = models.ImageField(null=True, upload_to=baptism_certificates_image_file_path)
    marriage_certificate = models.ImageField(null=True, upload_to=marriage_certificates_image_file_path)

如您所见age,这是一个计算属性。

我的观点如下

class ParishionerViewSet(viewsets.ModelViewSet):
    queryset = Parishioner.objects.all()
    serializer_class = serializers.ParishionerSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        first_name = self.request.query_params.get('first_name')
        last_name = self.request.query_params.get('last_name')
        gender = self.request.query_params.get('gender')
        address = self.request.query_params.get('address')
        fathers_name = self.request.query_params.get('fathers_name')
        mothers_name = self.request.query_params.get('mothers_name')
        age = int(self.request.query_params.get('age'))
        queryset = self.queryset
        
        if first_name:
            queryset = queryset.filter(first_name__contains=first_name)
        if last_name:
            queryset = queryset.filter(last_name__contains=last_name)
        if gender:
            queryset = queryset.filter(gender__contains=gender)
        if address:
            queryset = queryset.filter(address__contains=address)
        if fathers_name:
            queryset = queryset.filter(fathers_name__contains=fathers_name)
        if mothers_name:
            queryset = queryset.filter(mothers_name__contains=mothers_name)
        if age:
            queryset = queryset.filter(age__gte=age)
        return queryset.filter()

我想要的只是返回拥有age >= provides value. 因此,如果我向此 url 发送请求,http://localhost:8000/api/parishioners/?age=32 我会收到此错误 -->Cannot resolve keyword 'age' into field

那么如何使用此 urlhttp://localhost:8000/api/parishioners/?age=32 并获取年龄大于或等于 32 的对象?

标签: djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-queryset

解决方案


您不能在查询中使用模型的函数/属性。您需要将函数的逻辑带入查询中。

from django.db.models.functions import ExtractYear, Now

queryset = queryset.annotate(age=ExtractYear(Now()) - ExtractYear('dob')).filter(age__gte=age)

推荐阅读