django - 使用序列化程序 Django (DRF) 创建对象

标签 django django-rest-framework django-serializer

我正在尝试使用序列化程序在我的 View 中创建一个对象。 但是我的一个对象遇到了一个恼人的问题:

这就是我创建对象的方式:

editObject = Question_edit(
    question=question,
    description='CREATE Question: %s' % question.text,
    editor=user,
    notes=question.notes
)
print(editObject)      # return 'Question_edit object (None)'

serializer = Question_editSerializer(editObject)
json = JSONRenderer().render(serializer.data)
stream = io.BytesIO(json)
data = JSONParser().parse(stream)
serializer = Question_editSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()

这是我的Question_editSerializer:

class Question_editSerializer(serializers.ModelSerializer):
    time_since_edit = serializers.SerializerMethodField()

    class Meta:
        model = Question_edit
        fields = "__all__"

    def get_time_since_edit(self, object):
        date_edit = object.date
        time_delta = timesince(date_edit, timezone.now())
        return time_delta

    def create(self, validated_data):
        return Question_edit.objects.create(**validated_data)

还有我的Question_edit模型:

class Question_edit(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    description = models.TextField(max_length=500)
    editor = models.ForeignKey(
        CustomUser, on_delete=models.SET_NULL, null=True)
    notes = models.TextField(max_length=500, blank=True, null=True)

由于在上面的第一段代码中尝试使用序列化器创建对象,我得到了这个错误:

  File "/foodbook24-api/questions/api/serializers.py", line 44, in get_time_since_edit
    time_delta = timesince(date_edit, timezone.now())
  File "/usr/local/lib/python3.8/site-packages/django/utils/timesince.py", line 49, in timesince
    d = datetime.datetime(d.year, d.month, d.day)

Exception Type: AttributeError at /api/questionnaires/
Exception Value: 'NoneType' object has no attribute 'year'

完整的回溯:

Environment:


Request Method: POST
Request URL: http://localhost:8000/api/questionnaires/

Django Version: 3.1.3
Python Version: 3.8.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'rest_framework',
 'rest_framework.authtoken',
 'drfpasswordless',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'rest_auth',
 'rest_auth.registration',
 'django_filters',
 'corsheaders',
 'surveys',
 'questionnaire',
 'questions',
 'users',
 'foods',
 'utilities']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/generics.py", line 242, in post
    return self.create(request, *args, **kwargs)
  File "/foodbook24-api/questionnaire/api/views.py", line 184, in create
    return self.elaborateClientPOSTRequest(request)
  File "/foodbook24-api/questionnaire/api/views.py", line 114, in elaborateClientPOSTRequest
    self.create_question_edit_record(questionObject, request)
  File "/foodbook24-api/questionnaire/api/views.py", line 85, in create_question_edit_record
    json = JSONRenderer().render(serializer.data)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 548, in data
    ret = super().data
  File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 515, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/fields.py", line 1870, in to_representation
    return method(value)
  File "/foodbook24-api/questions/api/serializers.py", line 44, in get_time_since_edit
    time_delta = timesince(date_edit, timezone.now())
  File "/usr/local/lib/python3.8/site-packages/django/utils/timesince.py", line 49, in timesince
    d = datetime.datetime(d.year, d.month, d.day)

Exception Type: AttributeError at /api/questionnaires/
Exception Value: 'NoneType' object has no attribute 'year'

我在这里错过了什么?

最佳答案

在下面的代码中,您忘记保存editObject:

editObject = Question_edit(
    question=question,
    description='CREATE Question: %s' % question.text,
    editor=user,
    notes=question.notes
)
print(editObject)      # return 'Question_edit object (None)'

serializer = Question_editSerializer(editObject)
json = JSONRenderer().render(serializer.data)
stream = io.BytesIO(json)
data = JSONParser().parse(stream)
serializer = Question_editSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()

只有当对象保存到数据库时,Django 才会计算日期并将其存储在editObject.date 中。由于那没有发生,一旦您访问上面的 serializer.data,您的 get_time_since_edit() 方法就会尝试计算 None 之间的差异和 timezone.now(),导致错误 'NoneType' object has no attribute 'year'

您可以通过将上面的代码更改为以下代码来解决此问题:

editObject = Question_edit(
    question=question,
    description='CREATE Question: %s' % question.text,
    editor=user,
    notes=question.notes
)

editObject.save() # This will populate the `date` attribute with the current date/time

serializer = Question_editSerializer(editObject)
json = JSONRenderer().render(serializer.data)
stream = io.BytesIO(json)
data = JSONParser().parse(stream)
serializer = Question_editSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()

关于django - 使用序列化程序 Django (DRF) 创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65155286/

相关文章:

Django-rest-framework 序列化程序 : Create an object with foreign objects at the same time

python - Django REST 框架 : return 404 (not 400) on POST if related field does not exist?

django - 如何在没有 read_only=True 的情况下在 django rest 框架中使用 Foreign_Key 值而不是 id

python - Linux。 Heroku-Django。 Collectstatic 只读文件系统

python - Django 模型字段验证器未按应有的方式引发异常

python - 通过 Visual Studio 2017 在 Azure 中部署 Django Web 应用程序

django - 如何在 Webfaction 上使用 upload_to 和 MEDIA_ROOT 配置 Django ImageField?

javascript - Ember 数据 JSONAPIAdapter : fetch nested resources

Django请求框架 'ManyRelatedField'对象在修改get_fields中的查询集时没有属性 'queryset'

django - 将具有相关对象的模型对象序列化为 JSON