首页 > 解决方案 > Django Rest Framework 从两个模型返回所需的结果

问题描述

我有两个模型(客户,电影),当我点击 URL(api/customer/1)和点击 URL(api/customer/1/movies)时,我想返回(movie_name,customer_name,id)只想要电影名字。我们怎样才能做到这一点?

模型.py

class Customer(models.Model):
    name = models.CharField(max_length=200, null=True)

class Movie(models.Model):
    movie_name = models.CharField(max_length=200, null=True)
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)

序列化程序.py

class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id', 'name')

class MovieSerializer(serializers.ModelSerializer):

    class Meta:
        model = Movie
        fields = '__all__'

网址.py

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^api/customers/$', CustomerSerializer.as_view(), name='customers'),
]

笔记:

在此处输入图像描述

标签: python-3.xdjangodjango-rest-framework

解决方案


为此,您必须编写两个 url,但您可以使用一个视图和序列化程序来执行此操作,如下所示

网址

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/customers/<int:id>/', CustomerMovieView.as_view(check=True)),
    path('api/customers/<int:id>/movies/', CustomerMovieView.as_view(check=False)),
]

视图和序列化器

from rest_framework import generics, response, serializer


class MovieSerializer(serializers.ModelSerializer):
     customer_name = serializers.SerializerMethodField()
     def get_customer_name(self, instance):
         return instance.customer.name

     class Mete:
         model = Movie
         fields = '__all__'

     def to_representation(self, instance):
         data = super().to_representation(instance)
         if not self.context('check'):
             data.pop('customer_name', None)
             data.pop('customer', None)
         return data


class CustomerMovieView(generics.GenericAPIView):
     serializer_class = MovieSerializer
     check = True
     
     def get_serializer_context(self):
         context = super().get_serializer_context()
         context.update({'check': self.check})
         return context

     def get(self, request, *args, **kwargs):
         id = kwargs.get('id')
         movie = Movie.objects.get(id=id)
         serialized = self.get_serializer(movie)
         return response.Respoonse(serialized.data)
         

推荐阅读