【问题标题】:Django Rest Framework: Use URL parameter in serializerDjango Rest Framework:在序列化程序中使用 URL 参数
【发布时间】:2023-03-11 22:51:01
【问题描述】:

我的目标是在函数中使用 URL 参数作为变量并在序列化程序中输出。但是以下解决方案不起作用。有人知道为什么吗?

网址如下所示: 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', ]

【问题讨论】:

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


    【解决方案1】:

    我们需要在两个地方更新代码。

    1. views.py 中的DetailView。

    在此,我们正在更新上下文以包含 data_from。 (请注意,我们也可以直接在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. serializers.py 中的 OsdSerializer
    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']
       
    

    另一种方法是直接从序列化程序的上下文中访问请求对象。默认情况下,序列化程序上下文中包含请求对象。为此,只需按如下所述更新序列化程序

    serializers.py 中的 OsdSerializer

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

    【讨论】:

    • 我把这个放在哪里了?在 serializer.py 中对吗?
    • 没有。它将被放置在视图中。我刚刚更新了您的视图集的获取序列化程序上下文。
    • 但是我只会得到以下错误:字段名称date_from 对模型Application 无效。
    • 我已经更新了答案,你可以试试这个吗?
    • 你好VJ,谢谢你的解释。我试过了,但错误是一样的:字段名称date_from 对模型Application 无效。我已使用当前更改更新了问题中的代码。
    【解决方案2】:

    首先你需要将访问参数从kwargs改为request.GET

    如果您在 django '/user/<int:user_id>' 中有这样的 url,那么您可以通过 kwargs 访问。

    但是如果你发送一个 url 参数,像这样'/user/?user_id=1'。您通过请求对象访问。

    在您的情况下,我认为 rest_framework 会自动将请求发送到序列化程序。所以你可以这样做:

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

    【讨论】:

    • 感谢您的解释。我现在收到以下错误:字段名称date_from 对模型Application 无效。你知道为什么吗?我必须在模型中责备字段吗?
    • 你能用完整的序列化代码更新你的第一篇文章并写下错误发生在哪一行吗?那我可以帮你
    • 但是在不知道上下文的情况下,您得到的错误意味着您正在尝试访问不存在的应用程序模型中的字段date_from。你写了obj.date_fromApplication.objects.filter(date_from=..)之类的东西。
    • 我已经更新了代码并提供了带有错误消息的屏幕截图。
    • 使用 SerializerMethodField。 django-rest-framework.org/api-guide/fields/…
    猜你喜欢
    • 1970-01-01
    • 2016-12-18
    • 2017-06-04
    • 2014-04-13
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多