如何在Django Rest Framework

时间:2018-05-22 02:31:39

标签: python django django-rest-framework

我有两个模型,RoundtripTour,以及另一个名为RoundtripTour的模型,我可以用多对多方式链接这两个模型。我做了一个休息服务,通过反向引用返回Tour实例和所有RoundtripTour实例的列表,它运行正常,但服务返回RoundtripTour模型中的所有字段,我想只返回引用Roundtrip模型实例的字段。

这些是我的模特:

class Roundtrip(models.Model):
    name = models.CharField(max_length=70, verbose_name=_('Name'))
    code = models.CharField(max_length=8, verbose_name=_('Code'))
    duration = models.IntegerField(verbose_name=_('Duration'))
    description = models.TextField(verbose_name=_('Description'))

class Tour(models.Model):
    name = models.CharField(max_length=70, verbose_name=_('Name'))
    description = models.TextField(verbose_name=_('Description'))
    is_own = models.BooleanField(default=True, verbose_name=_('Is own tour?'))
    code = models.CharField(max_length=10, verbose_name=_('Code'))

class RoundtripTour(models.Model):
    roundtrip = models.ForeignKey(Roundtrip, on_delete=models.PROTECT, related_name='tours', verbose_name=_('Roundtrip'))
    tour = models.ForeignKey(Tour, on_delete=models.PROTECT, related_name='roundtrips', verbose_name=_('Tour'))
    day = models.IntegerField(verbose_name=_('Day'))

这是我的序列化器:

class TourRoundtripsSerializer(serializers.HyperlinkedModelSerializer):
    roundtrips = serializers.SerializerMethodField()

    def get_roundtrips(self, instance):
        queryset = [x.roundtrip for x in instance.roundtrips.all()]
        return RoundtripSerializer(queryset, many=True, context=self.context).data

class Meta:
    model = models.Tour
    fields = ('id', 'name', 'description', 'is_own', 'code', 'roundtrips')

这是我的观点:

class TourRoundtripsViewSet(viewsets.ModelViewSet):
    queryset = models.Tour.objects.all()
    serializer_class = serializers.TourRoundtripsSerializer

我希望roundtrips反向引用仅返回roundtrip模型(RoundtripTour模型的roundtrip字段)中的字段RoundtripTour。这可能吗?

我做了@Ykh建议的更改,但是我收到了错误。这是追溯:

Internal Server Error: /es/reservations_manager/roundtrips/1/composition
Traceback (most recent call last):
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 58, in retrieve
    return Response(serializer.data)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 560, in data
    ret = super(Serializer, self).data
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 527, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/fields.py", line 1855, in to_representation
    return method(value)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/Intellibook/ReservationsManagerApp/serializers.py", line 191, in get_hotels
    return HotelSerializer(queryset, many=True).data
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 765, in data
    ret = super(ListSerializer, self).data
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in to_representation
    self.child.to_representation(item) for item in iterable
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 527, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/Users/hugovillalobos/Documents/Code/IntellibookProject/IntellibookVenv/lib/python3.6/site-packages/rest_framework/relations.py", line 356, in to_representation
    "the serializer." % self.__class__.__name__
AssertionError: `HyperlinkedRelatedField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer.
[24/May/2018 14:23:52] "GET /es/reservations_manager/roundtrips/1/composition HTTP/1.1" 500 145268

2 个答案:

答案 0 :(得分:2)

class TourRoundtripsSerializer(serializers.HyperlinkedModelSerializer):
    roundtrips = serializers.SerializerMethodField()

    def get_roundtrips(self, instance):
        queryset = [x.roundtrip for x in instance.roundtrips.all()]
        return RoundtripSerializer(queryset, many=True,  context=self.context).data

    class Meta:
        model = models.Tour
        fields = ('id', 'name', 'description', 'is_own', 'code', 'roundtrips')
        depth = 1

使用SerializerMethodField获取您想要的任何内容。

答案 1 :(得分:0)

再添加一个序列化程序RoundtripsSerializer,如下所示,

class RoundtripsSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = RoundtripTour
        fields = ('roundtrip',)


class TourRoundtripsSerializer(serializers.HyperlinkedModelSerializer):
    roundtrips = RoundtripsSerializer(many=True, read_only=True)

    class Meta:
        model = Tour
        fields = ('id', 'name', 'description', 'is_own', 'code', 'roundtrips')
        depth = 1