Add extra parameter to serializer.data

Viewed 1615

I get three fields from rest api i.e name , phone number and email id in serializer but i want to store the datetime as well when i receive the api . in database i have created 4 columns i.e name , phone number, email id , created data . How can i add current date timeparameter to my serializer.data before saving it to posgtresql database table "table_userdetails". please help me with the answers because i am new to it

Below is the code for 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)

Below is the code for 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

Below is my code for serializer.py

class UserDetailsSerializer(serializers.ModelSerializer):

    class Meta:
        model=UserDetails
        fields='__all__'

I have added the context part in post method but how to add in serializer.data .please help me with the solution and what am i doing wrong here .any kind of help is appreciated . Thank you

3 Answers

Try this:

@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)

You don't need to set now to time directly as you could use auto_add_now on DateTimeField/DateField model field

There is no sense to keep date in CharField


For further reference you could update() your request.data dictionary with additional attribute as just setting new variable called context does nothing

You can pass extra parameters to the serializers save method. serializer.save(created_at=datetime.datetime.now())

Doing so you will have to take care of validating the data manually, as the serializer will directly save this to the database.

As per your requirement, for created_at field, you can use the auto_now_add=True attribute in your model field, this will automatically assign the current time to the created_at field. only during the time of creation. Similary for a updated_at field you can use auto_now=True.

Now if you want to pass extra context to the serializer, you can do so by overriding the __init__ method.

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__'

Then while initializing the serializer you can pass the value serializer = UserDetailsSerializer(data=request.data, time=datetime.datetime.now())

After that you can use this in the serializer methods. For your requirement, setting the auto_now_add attribute will be the best solution.

Edit: If you are using USE_TZ=True in your settings.py you should be using timezone.now()

from django.utils import timezone.now()

serializer.save(created_at=timezone.now())

Django uses UTC time saved to the database for a timezone aware object, which is converted to the localtime of the user as per the settings. Refer to docs for more information

Related