Django Rest - Using a SerializerMethodField and getting an error: 'QuerySet' object has no attribute 'birth_date'
Django Rest - Using a SerializerMethodField and getting an error: 'QuerySet' object has no attribute 'birth_date'
我是 Django 和 API 的新手,我想使用 Django Rest Framework 创建一个基于 API 的 Django。
这是我想要做的:
年龄范围报告的终点:
curl -H 'Content-Type: application/json' localhost:8000/reports/employees/age/
回复:
{
"younger": {
"id": "1",
"name": "Anakin Skywalker",
"email": "skywalker@ssys.com.br",
"department": "Architecture",
"salary": "4000.00",
"birth_date": "01-01-1983"},
"older": {
"id": "2",
"name": "Obi-Wan Kenobi",
"email": "kenobi@ssys.com.br",
"department": "Back-End",
"salary": "3000.00",
"birth_date": "01-01-1977"},
"average": "40.00"
}
到目前为止,这是我的代码:
employees/model.py:
class Employee(models.Model):
name = models.CharField(max_length=250, default='FirstName LastName')
email = models.EmailField(max_length=250, default='employee@email.com')
departament = models.CharField(max_length=250, default='Full-Stack')
salary = models.DecimalField(max_digits=15, decimal_places=2, default=0)
birth_date = models.DateField()
employees/serializers.py:
class EmployeeSerializer(serializers.ModelSerializer):
age = serializers.SerializerMethodField()
class Meta:
model = Employee
fields = ['id', 'name', 'email', 'departament', 'salary', 'birth_date', 'age']
def get_age(self, obj):
delta = datetime.now().year - obj.birth_date.year
return delta
class EmployeeAgeReportSerializer(serializers.Serializer):
youngest = EmployeeSerializer()
oldest = EmployeeSerializer()
# average = serializers.FloatField()
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
employees/views.py:
class EmployeeGenericViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet
):
queryset = Employee.objects.all()
serializer_class = EmployeeSerializer
lookup_field = 'pk'
在employees/services.py中我有:
class EmployeeAgeReport:
def __init__(self, youngest, oldest):
self.youngest = youngest
self.oldest = oldest
# self.average = average
def get_employee_age_report():
age_report_dict = Employee.objects.aggregate(
earliest_birth_date=Min("birth_date"),
oldest_birth_date=Max("birth_date")
)
youngest_employee = Employee.objects.filter(
birth_date=age_report_dict.get("earliest_birth_date")
).first()
oldest_employee = Employee.objects.filter(
birth_date=age_report_dict.get("oldest_birth_date")
)
return EmployeeAgeReport(
youngest=youngest_employee,
oldest=oldest_employee
)
但是当我尝试访问 http://localhost:8000/reports/employees/age/
时出现此错误:
Got AttributeError when attempting to get a value for field `birth_date` on serializer `EmployeeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'birth_date'.
完整追溯:
Traceback (most recent call last):
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
return get_attribute(instance, self.source_attrs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
instance = getattr(instance, attr)
During handling of the above exception ('QuerySet' object has no attribute 'birth_date'), another exception occurred:
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "D:\Programming\Desafios\Ssys\SSYS_Employee_Manager\applications\reports\views.py", line 21, in get
return Response(serializer.data)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 490, in get_attribute
raise type(exc)(msg)
Exception Type: AttributeError at /reports/employees/age/
Exception Value: Got AttributeError when attempting to get a value for field `birth_date` on serializer `EmployeeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'birth_date'.
我做错了什么,我该如何解决?
提前致谢。
试试这个,
oldest_employee = Employee.objects.filter( birth_date=age_report_dict.get("oldest_birth_date") ) here add .first() in the end like you did for youngest_employee.
oldest_employee
在此处获取列表而不是对象。
我是 Django 和 API 的新手,我想使用 Django Rest Framework 创建一个基于 API 的 Django。
这是我想要做的:
年龄范围报告的终点:
curl -H 'Content-Type: application/json' localhost:8000/reports/employees/age/
回复:
{
"younger": {
"id": "1",
"name": "Anakin Skywalker",
"email": "skywalker@ssys.com.br",
"department": "Architecture",
"salary": "4000.00",
"birth_date": "01-01-1983"},
"older": {
"id": "2",
"name": "Obi-Wan Kenobi",
"email": "kenobi@ssys.com.br",
"department": "Back-End",
"salary": "3000.00",
"birth_date": "01-01-1977"},
"average": "40.00"
}
到目前为止,这是我的代码:
employees/model.py:
class Employee(models.Model):
name = models.CharField(max_length=250, default='FirstName LastName')
email = models.EmailField(max_length=250, default='employee@email.com')
departament = models.CharField(max_length=250, default='Full-Stack')
salary = models.DecimalField(max_digits=15, decimal_places=2, default=0)
birth_date = models.DateField()
employees/serializers.py:
class EmployeeSerializer(serializers.ModelSerializer):
age = serializers.SerializerMethodField()
class Meta:
model = Employee
fields = ['id', 'name', 'email', 'departament', 'salary', 'birth_date', 'age']
def get_age(self, obj):
delta = datetime.now().year - obj.birth_date.year
return delta
class EmployeeAgeReportSerializer(serializers.Serializer):
youngest = EmployeeSerializer()
oldest = EmployeeSerializer()
# average = serializers.FloatField()
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
employees/views.py:
class EmployeeGenericViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet
):
queryset = Employee.objects.all()
serializer_class = EmployeeSerializer
lookup_field = 'pk'
在employees/services.py中我有:
class EmployeeAgeReport:
def __init__(self, youngest, oldest):
self.youngest = youngest
self.oldest = oldest
# self.average = average
def get_employee_age_report():
age_report_dict = Employee.objects.aggregate(
earliest_birth_date=Min("birth_date"),
oldest_birth_date=Max("birth_date")
)
youngest_employee = Employee.objects.filter(
birth_date=age_report_dict.get("earliest_birth_date")
).first()
oldest_employee = Employee.objects.filter(
birth_date=age_report_dict.get("oldest_birth_date")
)
return EmployeeAgeReport(
youngest=youngest_employee,
oldest=oldest_employee
)
但是当我尝试访问 http://localhost:8000/reports/employees/age/
时出现此错误:
Got AttributeError when attempting to get a value for field `birth_date` on serializer `EmployeeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'birth_date'.
完整追溯:
Traceback (most recent call last):
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
return get_attribute(instance, self.source_attrs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
instance = getattr(instance, attr)
During handling of the above exception ('QuerySet' object has no attribute 'birth_date'), another exception occurred:
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "D:\Programming\Desafios\Ssys\SSYS_Employee_Manager\applications\reports\views.py", line 21, in get
return Response(serializer.data)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\Laila\.virtualenvs\SSYS_Employee_Manager-Ih3-mAGZ\lib\site-packages\rest_framework\fields.py", line 490, in get_attribute
raise type(exc)(msg)
Exception Type: AttributeError at /reports/employees/age/
Exception Value: Got AttributeError when attempting to get a value for field `birth_date` on serializer `EmployeeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'birth_date'.
我做错了什么,我该如何解决?
提前致谢。
试试这个,
oldest_employee = Employee.objects.filter( birth_date=age_report_dict.get("oldest_birth_date") ) here add .first() in the end like you did for youngest_employee.
oldest_employee
在此处获取列表而不是对象。