【问题标题】:Add extra parameter to serializer.data向 serializer.data 添加额外参数
【发布时间】:2021-01-05 05:35:00
【问题描述】:

我从 rest api 获得三个字段,即序列化程序中的姓名、电话号码和电子邮件 ID,但我想在收到 api 时也存储日期时间。在数据库中,我创建了 4 列,即姓名、电话号码、电子邮件 ID、创建数据。 如何在将当前日期时间参数保存到 posgtresql 数据库表“table_userdetails”之前将其添加到我的 serializer.data。请帮我解答,因为我是新手

下面是views.py的代码

@api_view(['GET', 'POST'])
def UserInfo(request):
    if request.method == 'GET':
        snippets = UserDetails.objects.all()
        serializer=UserDetailsSerializer(snippets, many=True)
        return Response(serializer.data)
    elif request.method =='POST':
        context=datetime.datetime.now()
        serializer = UserDetailsSerializer(data=request.data)
        print("serializer",serializer)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

下面是 Models.py 的代码

class UserDetails(models.Model):
   name=models.CharField(max_length=255)
   mobile_no=models.CharField(max_length=255)
   email_id=models.CharField(max_length=255)
   user_id=models.IntegerField(primary_key=True)
   created_date=models.CharField(max_length=255)

   class Meta:
      db_table=table_userdetails 
    
   def __str__(self):
       return self.response

下面是我的 serializer.py 代码

class UserDetailsSerializer(serializers.ModelSerializer):

    class Meta:
        model=UserDetails
        fields='__all__'

我已经在 post 方法中添加了上下文部分,但是如何添加 serializer.data。请帮助我解决问题以及我在这里做错了什么。感谢任何帮助。 谢谢

【问题讨论】:

    标签: python django django-rest-framework django-serializer


    【解决方案1】:

    您不需要现在直接设置时间,因为您可以在 DateTimeField/DateField 模型字段上使用 auto_add_now

    在 CharField 中保持日期是没有意义的


    为了进一步参考,您可以 update() 您的 request.data 字典与附加属性,因为只是设置名为 context 的新变量没有任何作用

    【讨论】:

      【解决方案2】:

      试试这个:

      @api_view(['GET', 'POST'])
      def UserInfo(request):
          if request.method == 'GET':
              snippets = UserDetails.objects.all()
              serializer=UserDetailsSerializer(snippets, many=True)
              return Response(serializer.data)
          elif request.method =='POST':
              serializer = UserDetailsSerializer(data=request.data)
              print("serializer",serializer)
      
              data = serializer.data #fetch the serializer data
              #add current time as key-value pair in data as serializer.data returns a dictionary
              data['current_time'] = datetime.datetime.now()
      
              if serializer.is_valid():
                  serializer.save()
      
                  #return the data object/dictionary
                  return Response(data, status=status.HTTP_201_CREATED)
              return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
      

      【讨论】:

      • 在尝试此操作时我收到此错误“当序列化程序传递data 关键字参数时,您必须在尝试访问序列化的.data 表示之前调用.is_valid()。您应该调用@请先访问 987654325@,或者改为访问 .initial_data。”
      • 哦,好吧,我会编辑它。这两行都需要在serializer.is_valid()之后添加。
      • 我仍然收到一些错误“访问 serializer.data 后无法调用 .save()。如果您需要在提交到数据库之前访问数据,然后检查 'serializer.validated_data'。”@Ajay林加亚语
      • serializer.save() 之后调用它。这次会成功的。
      • 很抱歉问了这么多问题,但是在 serializer.save() 行之后调用不会在我的数据库中存储日期时间值。我可以看到具有 datetime fileld 的 json 响应,但在数据库中它在列中显示空值。我做错了什么步骤吗?除了当前日期时间之外,所有其他字段都存储在表中。
      【解决方案3】:

      您可以将额外的参数传递给序列化程序的保存方法。 serializer.save(created_at=datetime.datetime.now())

      这样做您必须手动验证数据,因为序列化程序会直接将其保存到数据库中。

      根据您的要求,对于created_at 字段,您可以在模型字段中使用auto_now_add=True 属性,这将自动将当前时间分配给 created_at 字段。仅在创作期间。 updated_at 字段的相似之处,您可以使用 auto_now=True

      现在,如果您想将额外的上下文传递给序列化程序,您可以通过覆盖 __init__ 方法来实现。

      class UserDetailsSerializer(serializers.ModelSerializer):
      
          def __init__(self, *args, **kwargs):
              time = kwargs.pop('time')
              super().__init__(*args, **kwargs)
              self.time = time
      
          class Meta:
              model=UserDetails
              fields='__all__'
      

      然后在初始化序列化程序时,您可以传递值 serializer = UserDetailsSerializer(data=request.data, time=datetime.datetime.now())

      之后,您可以在序列化方法中使用它。根据您的要求,设置auto_now_add 属性将是最佳解决方案。

      编辑:如果您在 settings.py 中使用 USE_TZ=True,您应该使用 timezone.now()

      from django.utils import timezone.now()
      
      serializer.save(created_at=timezone.now())
      

      Django 使用保存到数据库的 UTC 时间作为时区感知对象,根据设置将其转换为用户的本地时间。 更多信息请参考docs

      【讨论】:

      • 感谢您的解决方案!!! auto_now_add 完美地为我工作,唯一的问题是我将 settings.py 中的时区从“UTC”更改为 Asia/kolkata。我收到一条警告消息----“RuntimeWarning:DateTimeField UserDetails.update_date 收到了一个幼稚的日期时间(2021-01- 05 18:46:01.538564) 时区支持处于活动状态。"
      • 如果您在 settings.py 文件中使用 USE_TZ=True ,那么您将需要使用 timezone.now() 来获取时区感知对象。请参阅上面的编辑以进行澄清。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多