Django Rest Framework:在序列化程序中使用 URL 参数
Django Rest Framework: Use URL parameter in serializer
我的目标是使用 URL 参数作为函数中的变量,并在序列化程序中输出它。但以下解决方案不起作用。有人知道为什么吗?
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', ]
首先,您需要将访问参数从 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')
我们需要在两个地方更新代码。
- views.py 中的详细视图。
在此,我们正在更新上下文以包含 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})
...
- OsdSerializer 在 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']
另一种方法是直接从序列化程序的上下文中访问请求对象。默认情况下,序列化程序上下文中包含请求对象。为此,只需按以下所述更新序列化程序
OsdSerializer 在 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']
我的目标是使用 URL 参数作为函数中的变量,并在序列化程序中输出它。但以下解决方案不起作用。有人知道为什么吗?
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', ]
首先,您需要将访问参数从 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')
我们需要在两个地方更新代码。
- views.py 中的详细视图。
在此,我们正在更新上下文以包含 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})
...
- OsdSerializer 在 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']
另一种方法是直接从序列化程序的上下文中访问请求对象。默认情况下,序列化程序上下文中包含请求对象。为此,只需按以下所述更新序列化程序
OsdSerializer 在 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']