简体   繁体   English

Django Rest 框架:自定义视图

[英]Django Rest Framework: Custom Views

i have a django installation with currently two apps ( common / destinations ) and i want to create custom api views across these apps.我有一个 django 安装,目前有两个应用程序(公共/目的地),我想在这些应用程序中创建自定义 api 视图。

in common i have a model country共同点,我有一个模范国家

models.py app common models.py 应用程序常见

from django.db import models

# Create your models here.

class Country(models.Model):
    CONTINENTS = (
        ('Europe', 'Europe'),
        ('Asia', 'Asia'),
        ('Africa', 'Africa'),
        ('northamerica', 'North America'),
        ('southamerica', 'South America'),
        ('australia', 'Australia')
    )
    name = models.CharField(max_length=120)
    code = models.CharField(max_length=2)
    continent = models.CharField(max_length=11, choices=CONTINENTS)
    content = models.TextField()
    image = models.FileField()

models.py app destination models.py 应用程序目的地

from django.db import models

# Create your models here.

class Destination(models.Model):
    name = models.CharField(max_length=120)
    code = models.CharField(max_length=3)
    country = models.ForeignKey("common.Country", on_delete=models.CASCADE)
    image = models.FileField()

serializers.py app destination serializers.py 应用程序目标

from rest_framework import serializers
from common.serializers import CountrySerializer
from .models import Destination 

class DestinationSerializer(serializers.ModelSerializer):

country = CountrySerializer()

class Meta:
    model = Destination
    fields = ("id", "name", "code", "country", "image")

views.py app destination views.py 应用程序目的地

from rest_framework import views
from rest_framework.response import Response
from .serializers import DestinationSerializer, ImageSerializer
from .models import Destination

# Create your views here.

class DestinationView(views.APIView):
    def get(self, request, code):
        destination =  Destination.objects.filter(code=code.upper())
        if destination:
            serializer = DestinationSerializer(destination, many=True)
            return Response(status=200, data=serializer.data)
        return Response(status=400, data={"Destination not found"})

When i make a API call /api/destination/PMI everything works.当我进行 API 调用 /api/destination/PMI 时,一切正常。 i get my destination from destination app and country from common app.我从目的地应用程序和国家从通用应用程序获取我的目的地。

**GET /api/destination/**

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 1,
        "name": "Palma de Mallorca",
        "code": "PMI",
        "country": {
            "id": 1,
            "name": "Spain",
            "code": "ES",
            "continent": "Europe",
            "content": "Lorem Ipsum",
            "image": "http://localhost:1000/media/logo.svg"
        },
        "image": "http://localhost:1000/media/2020-08-03_07-40.png"
    }
]

Now i want to create a view which only returns the images from common / destination现在我想创建一个视图,它只返回来自公共/目的地的图像

eg例如

GET **/api/destination/pmi/image**
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
    {
         "code": "pmi",
         "destination_image" : "image.png",
         "country_image" : "country.png" 
    }
]

how, if possible, can i achieve that?如果可能的话,我怎样才能做到这一点?

One easy and clean way to do that is to have an extra serializer for your view like:一种简单而干净的方法是为您的视图添加一个额外的序列化程序,例如:

class ExtraSerializer(serializers.ModelSerializer):
    destination_image = serializers.SerializerMethodField()
    country_image = serializers.SerializerMethodField()

    class Meta:
        model = Destination
        fields = (
            'code', 'destination_image', 'country_image'
        )

    def get_destination_image(self, obj):
        req = self.context['request']
        # build_absolute_uri will convert your related url to absolute url
        return req.build_absolute_uri(obj.image.url)

    def get_country_image(self, obj):
        req = self.context['request']
        return req.build_absolute_uri(obj.country.image.url)

Also note that you should pass the request from your view to context of your serializer to build an absolute url (Example: ExtraSerializer(queryset, many=True, context={'request': self.request}) or context={'request': request} if you're using same APIView as before) and then use the data of this serializer.另请注意,您应该将请求从视图传递到序列化程序的上下文以构建绝对 url(例如: ExtraSerializer(queryset, many=True, context={'request': self.request})context={'request': request}如果您使用与以前相同的APIView ),然后使用此序列化程序的数据。

class All_HomePage(APIView):

    def get(self,request):

        #get destination_data
        data = Destination.objects.all()
        destination_ser = DestinationSerializer(data,many=True)
        destination_data=[]
        for record in destination_ser.data:
            code = record['code']
            image = record['image']
            destination_data.append({"code":code ,"destination_image":image})


        #get country_data
        data = Country.objects.all()
        country_ser = CountrySerializer(data,many=True)
        country_data=[]
        for record in country_ser.data:
            image = record['image']
            country_data.append({"country_image":image,})


        return Response({
            "destination_data":destination_data, "country_data":country_data,
            })


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM