4

My goal is to use a URL parameter as a variable in a function and output it in the serializer. But the following solution doesnt work. Anybody know why?

The URL looks like this: http://127.0.0.1:8000/v1/water-bodies/?from=2013-02-17&to=2013-02-18

models.py

class Application(models.Model):
    """Database models for application information"""

    name = models.CharField(max_length=255)
    machine_name = models.SlugField(max_length=255, allow_unicode=True)
    description = models.TextField(blank=True, null=True)
    indice_to_use = models.ForeignKey('Indice', on_delete=models.PROTECT, blank=True, null=True)

    def __str__(self):
        return self.name

views.py

class DetailView(APIView):
    def get_serializer_context(self):
        context = super().get_serializer_context()
        context["date_from"] = self.request.query_params.get("from", None)
        return context

    def get(self, request, machine_name):
        application = Application.objects.get(machine_name=machine_name)
        serializer = OsdSerializer(application)

        return Response({"Everything you need to analyzing "+application.name: serializer.data})

serializer.py

class OsdSerializer(serializers.ModelSerializer):
    bands = BandSerializer(source='indice_to_use.needed_bands', many=True)
    satellite = SatelliteSerializer(source='indice_to_use.satellite_to_use')
    indice = IndiceSerializer(source='indice_to_use')

    def get_alternate_name(self, obj):
        return self.context.get('date_from')

    class Meta:
        model = Application
        fields = ['machine_name', 'name', 'description', 'indice', 'satellite', 'bands', 'date_from', ]

enter image description here

enter image description here

3 Answers 3

4

We would be required to update the code at two places.

  1. DetailView in views.py.

In this, we are updating context to include data_from. (please note, we can also access this directly in the serialzier)

class DetailView(APIView):
 ...
    def get(self, request, machine_name):
        application = Application.objects.get(machine_name=machine_name)
        serializer = OsdSerializer(application, context={
           "date_from": request.query_params.get("from")
        })

        return Response({"Everything you need to analyzing "+application.name: serializer.data})
 ...
  1. OsdSerializer in the serializers.py
class OsdSerializer(serializers.ModelSerializer):

   bands = BandSerializer(source='indice_to_use.needed_bands', many=True)
   satellite = SatelliteSerializer(source='indice_to_use.satellite_to_use')
   indice = IndiceSerializer(source='indice_to_use')
   alternate_name = serializers.SerializerMethodField()   

   def get_alternate_name(self, obj):
        return self.context.get('date_from')

   class Meta:
        model = Application
        fields = ['machine_name', 'name', 'description', 'indice', 'satellite', 'bands', 'date_from', 'alternate_name']
   

Another approach would be to access the request object directly from the context of the serializer. By default, the serializer context contains the request object in it. To do so, just update the serializer as mentioned below

OsdSerializer in the serializers.py

class OsdSerializer(serializers.ModelSerializer):

   bands = BandSerializer(source='indice_to_use.needed_bands', many=True)
   satellite = SatelliteSerializer(source='indice_to_use.satellite_to_use')
   indice = IndiceSerializer(source='indice_to_use')
   alternate_name = serializers.SerializerMethodField()   

   def get_alternate_name(self, obj):
        return self.context.get('request').query_params.get('from', None)
  
   class Meta:
        model = Application
        fields = ['machine_name', 'name', 'description', 'indice', 'satellite', 'bands', 'date_from', 'alternate_name']
   
Sign up to request clarification or add additional context in comments.

11 Comments

Where I have place this? In the serializer.py right?
No. It will be placed in views. I have just updated the get serializer context of your viewset.
But then I'll just get the following error: Field name date_from is not valid for model Application.
i have updated the answer, can you try this ?
Hey VJ, thanks for your explanations. I've tried it, but the error is the same: Field name date_from is not valid for model Application. I've updated the code in my question with the current changes.
|
2

First you need to change from accessing the parameter from kwargs to request.GET instead.

If you have a url like this in django '/user/<int:user_id>' then you access through kwargs.

But if you send a url parameter, like this '/user/?user_id=1'. You access through the request object.

In your situation, I think rest_framework will send the request to the serializer automatically. So you can do something like this:

def get_alternate_name(self, obj):
    date_from = self.request.GET.get('from')

7 Comments

Thanks for your explanaition. I get now the following error: Field name date_from is not valid for model Application. Do you know why? Do I have to reproach the field in the model?
Can you update your first post with complete code for serializer and write which line the error occured on? Then I can help you
But without knowing the context, the error you get means you're trying to access the field date_from in Application model which does not exists. You written something like obj.date_from or Application.objects.filter(date_from=..).
I've updated the code and provide a screenshot with the error message.
|
0
date=self.context.get('request').parser_context.get('kwargs').get(
        'edate')

1 Comment

Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, can you edit your answer to include an explanation of what you're doing and why you believe it is the best approach?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.