Reputation: 155
i have a django installation with currently two apps ( common / destinations ) and i want to create custom api views across these apps.
in common i have a model country
models.py app common
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
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
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
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. 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
e.g.
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?
Upvotes: 1
Views: 4980
Reputation: 2110
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.
Upvotes: 1
Reputation: 694
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,
})
Upvotes: 0