I'm building a rest API for a media library.
Here are some of my python code, I have simplify them a bit, so only the necessary code is included, to have a better overview about the current problem.
models.py:
class MediaSeries(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(blank=True)
class MediaSeriesEntries(models.Model):
serie = models.ForeignKey(MediaSeries, related_name='series',
db_column='seriesID', null=True,
on_delete=models.SET_NULL)
file = models.ForeignKey(MediaFiles, related_name='serie_set',
db_column='fileID', null=True,
on_delete=models.SET_NULL)
class MediaFiles(models.Model):
youtube = models.CharField(max_length=300, blank=True)
name = models.CharField(max_length=300)
screeningPause = models.BooleanField(default=0)
duration = models.BigIntegerField(default=0)
creatingDate = models.DateTimeField(default=now)
class Library(models.Model):
media = models.ForeignKey(MediaFiles, related_name='library_set',
db_column='fileID', null=True,
on_delete=models.SET_NULL)
visits = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
views.py:
class LibraryMediaFilter(filters.FilterSet):
class Meta:
model = Library
fields = ['media__name', 'media__duration',
'media__youtube', 'media__creatingDate']
class LibraryMediaViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows the library to be viewed.
Example ordering:
http://127.0.0.1:8000/api/library-media/?ordering=media__creatingDate
"""
queryset = Library.objects.all() \
.exclude(media__youtube="").exclude(media__screeningPause=True)
serializer_class = LibraryMediaSerializer
pagination_class = LibraryResultsSetPagination
filter_backends = (filters.DjangoFilterBackend, OrderingFilter)
filterset_class = LibraryMediaFilter
ordering_fields = ['media__serie_set__serie__name', 'media__name',
'media__creatingDate', 'visits', 'likes']
serializers.py:
class LibraryMediaSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='media.name', read_only=True)
duration = serializers.IntegerField(source='media.duration',
read_only=True)
youtube = serializers.CharField(source='media.youtube', read_only=True)
creatingDate = serializers.DateTimeField(source='media.creatingDate',
read_only=True)
serie_set = SeriesEntriesSerializer(source='media.serie_set',
read_only=True, many=True)
class Meta:
model = Library
fields = ('visits', 'likes', 'name', 'duration', 'youtube',
'creatingDate', 'serie_set')
When I call now the api with http://example.org/api/library-media/ I get this result:
{
"visits": 0,
"likes": 0,
"name": "example movie",
"duration": 9505000,
"youtube": "https://youtu.be/34345",
"creatingDate": "2013-01-01T01:00:00+01:00",
"serie_set": []
},
{
"visits": 0,
"likes": 0,
"name": "example serie",
"duration": 3436000,
"youtube": "https://youtu.be/z0c4rLCcyVE",
"creatingDate": "2013-01-01T01:00:00+01:00",
"serie_set": [
{
"name": "Das große Ganze",
"description": ""
}
]
},
Now I would like to filter against empty and not empty serie_set, with something like:
http://example.org/api/library-media/media__serie_set__isempty=true
or:
http://example.org/api/library-media/media__serie_set__isempty=false
Related
Here is my code:
# VIEW.PY
def retrieve(self, request, pk=None):
variant_id = request.get('variant_id')
queryset = Category.objects.filter(category_id=pk)
querysetSerializer = CategoryServiceListSerializer(queryset, many=True)
i want to filter variant_id from Variant so that it display only that particular variuant. Not sure where changes need to be made in views or serialzier.
im assuming this could be solution
queryset = Category.objects.filter(category_id=pk,variant__in = variant_id)
but getting error TypeError: 'int' object is not iterable
# MODELS.PY
class Category(models.Model):
category_id = models.AutoField(primary_key=True)
category_name = models.CharField(max_length=50)
category_icon = models.CharField(max_length=500, null=True, blank=True)
category_image = models.CharField(max_length=500, null=True, blank=True)
category_description = models.CharField(max_length=1000, null=True, blank=True)
active_status = models.BooleanField(default=True)
class Variant(models.Model):
variant_id = models.AutoField(primary_key=True)
service_id = models.ManyToManyField(Services)
category_id = models.ManyToManyField(Category)
variant_name = models.CharField(max_length=100)
variant_icon = models.CharField(max_length=1000, null=True, blank=True)
variant_image = models.CharField(max_length=1000, null=True, blank=True)
variant_description = models.CharField(max_length=5000, null=True, blank=True)
active_status = models.BooleanField(default=True)
# SERIALIZER.PY
class CategoryServiceListSerializer(serializers.ModelSerializer):
variant = VariantServiceSerializer(many=True, source="variant_set")
class Meta:
fields = "__all__"
model = Category
class VariantServiceSerializer(serializers.ModelSerializer):
class Meta:
model = Variant
fields = "__all__"
output:
"data": {
"category_id": 1,
"category_name": "Home Cleaning",
"variant": [
{
"variant_id": 1,
"variant_name":
},
{
"variant_id": 2,
"variant_name":
},
{
"variant_id": 3,
"variant_name":
},
{
"variant_id": 2,
"variant_name":
}
]
}
Expected_output:
req:
{"variant_id:1}
responce:
{
"category_id": 1,
"category_name": "Home Cleaning",
"variant": {
"variant_id": 1,
"variant_name":
}
One thing you can do is to make variant a SerializerMethodField then filter against parameters passed in the context.
In your view:
def retrieve(self, request, pk=None):
variant_id = request.get('variant_id')
queryset = Category.objects.filter(category_id=pk)
querysetSerializer = CategoryServiceListSerializer(queryset, many=True, context={'variant_id': variant_id})
[...]
In your serializer:
class CategoryServiceListSerializer(serializers.ModelSerializer):
variant = SerializerMethodField()
def get_variant(self, instance):
variant_id = self.context.get('variant_id')
if variant_id:
variants = instance.variant_set.filter(variant_id=variant_id)
else:
variants = instance.variant_set.all()
return VariantServiceSerializer(variants, many=True).data
class Meta:
fields = "__all__"
model = Category
Hi I'm new to django rest framework and I'm trying to serialize 3 nested models. The relationships are:
hotel_social_media_type has a one to many relationship to hotel_social_media
and hotel has one to many relationship to hotel_social_media. Right now I can only serialized hotel to hotel_social_media but I can't serialize hotel_social_media_type.
Here's my serializers:
class SocialMediaTypeSerializer(serializers.ModelSerializer):
"""Serializes social media type"""
class Meta:
model = models.SocialMediaType
fields = ('name', 'icon', 'url')
class HotelSocialMediaSerializer(serializers.ModelSerializer):
"""Serializes media files"""
hotel_social_media_type = SocialMediaTypeSerializer(many=False, read_only=True)
class Meta:
model = models.HotelSocialMedia
fields = ('url', 'hotel_social_media_type')
class HotelSerializer(serializers.ModelSerializer):
"""Serializes Restaurat, Bars, TouristInformation and Tourist Spots """
hotel_images = HotelImageSerializer(many=True, read_only=True)
hotel_social_media = HotelSocialMediaSerializer(many=True, read_only=True)
class Meta:
model = models.Hotel
fields = ('id', 'name', 'hotel_images', 'hotel_social_media')
Models:
class Hotel(models.Model):
"""Database model for hotels"""
name = models.CharField(max_length=50)
def __str__(self):
"""Return the model as a string"""
return self.name
class HotelImage(models.Model):
"""Image upload for hotel"""
name = models.CharField(max_length=50)
description = models.CharField(max_length=250)
path = models.ImageField(upload_to='images/')
created_on = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
hotel = models.ForeignKey(Hotel, related_name='hotel_images', on_delete=models.CASCADE, null=True)
def __str__(self):
"""Return the model as a string"""
return self.name
class SocialMediaType(models.Model):
"""Social Media Type eg: fb, twitter"""
name = models.CharField(max_length=50)
icon = models.ImageField(upload_to='images/')
url = models.CharField(max_length=50)
def __str__(self):
"""Return the model as a string"""
return self.name
class HotelSocialMedia(models.Model):
"""Social Media"""
hotel = models.ForeignKey(Hotel, related_name='hotel_social_media', on_delete=models.CASCADE, null=True)
type = models.ForeignKey(SocialMediaType, related_name='hotel_social_media_type', on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=50)
url = models.CharField(max_length=50)
def __str__(self):
"""Return the model as a string"""
return self.name
Current result is:
{
"id": 1,
"name": "Alta Vista",
"hotel_images": [
{
"id": 1,
"name": "Alta Vista",
"path": "http://127.0.0.1:8000/media/images/hotel-1.jpg"
}
],
"hotel_social_media": [
{
"url": "https://www.facebook.com/abscbnNEWS"
}
]
}
What I want is:
{
"id": 1,
"name": "Alta Vista",
"hotel_images": [
{
"id": 1,
"name": "Alta Vista",
"path": "http://127.0.0.1:8000/media/images/hotel-1.jpg"
}
],
"hotel_social_media": [
{
"url": "https://www.facebook.com/abscbnNEWS",
"hotel_social_media_type": {
"name": "Facebook",
"icon": "http://127.0.0.1:8000/media/images/fb-1.jpg"
}
}
]
}
`hotel_social_media` must also display `hotel_social_media_type`
Based on your model, you must use type keyword instead of hotel_social_media_type in your HotelSocialMediaSerializer. Because your HotelSocialMedia has type field for relation with HotelSocialMediaType.To change keyword can solve your problem.
class HotelSocialMediaSerializer(serializers.ModelSerializer):
"""Serializes media files"""
type = SocialMediaTypeSerializer(many=False, read_only=True)
class Meta:
model = models.HotelSocialMedia
fields = ('url', 'type')
If you want to use hotel_social_media_type keyword, you can use SerializerMethodField like that:
class HotelSocialMediaSerializer(serializers.ModelSerializer):
"""Serializes media files"""
hotel_social_media_type = serializers.SerializerMethodField()
class Meta:
model = models.HotelSocialMedia
fields = ('url', 'hotel_social_media_type')
def get_hotel_social_media_type(self.obj):
serializer = SocialMediaTypeSerializer(obj.type)
return serializer.data
I would like to output a field that counts the number of Candidat in Candidat Model. I am currently using the following serializer:
class CountCSerializer(serializers.ModelSerializer):
user_count = serializers.SerializerMethodField()
class Meta:
model = Candidat
fields = ( 'user_count',)
def get_user_count(self, obj):
return Candidat.objects.count()
and the following api:
class CountCViewSet(ModelViewSet):
queryset = Candidat.objects.all()
serializer_class = CountCSerializer
urls.py:
router.register(r'CountC', CountCViewSet, base_name='users-count')
models.py:
class Candidat(models.Model):
name = models.CharField(max_length=50)
lastName = models.CharField(max_length=50)
email = models.CharField(max_length=50)
tel = models.CharField(max_length=50, default=0)
password = models.CharField(max_length=50)
civility = models.CharField(max_length=50)
birthDate = models.DateField(auto_now=False, auto_now_add=False)
gouvernorate = models.CharField(max_length=50)
def __str__(self):
return "Candidat: {}".format(self.name)
But im getting nothing!
Any help in the matter would be much appreciated.
I was looking for the same and noticed that ModelViewSet generates a count by default. You can see it by navigating to the endpoint in a browser or checking the response body in Postman.
Example:
{
"count": 10,
"next": null,
"previous": null,
"results": [
{
"id": 62,
"entity_name": "The company name",
"entity_website_url": "thecompany.com",
"entity_city": "Los Angeles",
"entity_state": "CA"
}
...
]
}
I am programming django based web site using django rest-framework.
I want to use rest-framework to get model's data.
this is my model.py
class TimeTable(models.Model):
subject_name = models.CharField(max_length=50)
subject_code = models.CharField(max_length=10, unique=True)
classification = models.CharField(max_length=50)
professor = models.CharField(max_length=50)
department = models.CharField(max_length=50)
credit = models.CharField(max_length=1)
year = models.CharField(max_length=4, default='2018')
semester = models.CharField(max_length=1, default='1')
def __str__(self):
return self.subject_code + '-' + self.subject_name
class Class(models.Model):
owner = models.ForeignKey(Profile, null=True)
timetable = models.ForeignKey(TimeTable, null=True)
grade = models.FloatField()
this is serializer.py
class TimeTableSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = TimeTable
fields = ('url', 'subject_name', 'subject_code', 'classification', 'professor', 'department', 'credit', 'year', 'semester')
class ClassSerializer(serializers.HyperlinkedModelSerializer):
timetables = TimeTableSerializer(read_only=True)
class Meta:
model = Class
fields = ('url','owner', 'timetable', 'grade', 'timetables')
I want to get JSON response Like this
(http://localhost:8000/api/classes/)
[
{
"url": "http://localhost:8000/api/classes/8/",
"owner": "http://localhost:8000/api/profiles/19/",
"timetable": "http://localhost:8000/api/timetables/3/",
"grade": 4.5
"timetables": {
"url": "http://localhost:8000/api/timetables/3/",
"subject_name": "Artificial Inteligence",
"subject_code": "3413513413",
"classification": "major",
"professor": "John Lee",
"department": "software",
"credit": "3",
"year": "2018",
"semester": "1"
}
}
]
but i got this
[
{
"url": "http://localhost:8000/api/classes/8/",
"owner": "http://localhost:8000/api/profiles/19/",
"timetable": "http://localhost:8000/api/timetables/3/",
"grade": 4.5
}
]
How Can I get TimeTable's JSON data in Class JSON??
class ClassSerializer(serializers.HyperlinkedModelSerializer):
timetable = TimeTableSerializer(read_only=True)
class Meta:
model = Class
fields = ('url','owner', 'timetable', 'grade')
I am working on a deals/coupon selling website. I have following models, (excluding extra details).
class Order(models.Model):
email = models.EmailField(max_length=200, null=False)
phone_number = models.CharField(max_length=10, null=False)
shipping_address = models.TextField(blank=True,null=True)
coupon_code = models.CharField(max_length=20,null=True,blank=True)
gross_total = models.FloatField(default=0.0)
class Meta:
db_table = 'order'
class OrderDetail(models.Model):
order = models.ForeignKey(Order,related_name='order_details')
package = models.ForeignKey(Package)
quantity = models.IntegerField(null=False)
unit_price = models.FloatField(default=0.0)
class Meta:
db_table = 'order_detail'
class Coupon(models.Model):
order_detail = models.ForeignKey(OrderDetail,related_name='coupons')
code = models.CharField(max_length=200, null=False, unique=True)
maximum_usage_count = models.IntegerField(null=False)
used_count = models.IntegerField(default=0)
valid_from = models.DateTimeField(null=False)
valid_to = models.DateTimeField(null=False)
class Meta:
db_table = 'coupon'
My serializers for these are,
class CouponSerializer(serializers.Serializer):
class Meta:
model = Coupon
fields = ['id', 'code', 'maximum_usage_count', 'used_count', 'valid_from', 'valid_to', 'created_at',
'updated_at', 'is_active']
class OrderDetailSerializer(serializers.Serializer):
coupons = CouponSerializer(read_only=True)
class Meta:
model = OrderDetail
fields = ['id', 'package', 'quantity', 'unit_price', 'created_at', 'updated_at', 'is_active']
class OrderSerializer(serializers.ModelSerializer):
order_details = OrderDetailSerializer(read_only=True,many=True)
class Meta:
model = Order
fields = ['id','email', 'phone_number', 'shipping_address', 'coupon_code', 'gross_total','order_details']
In my listapiview, for fetching all orders, I have specified the order serializer. The api is working fine but is not able to serialize the reverse relation ship models. I am getting following response.
{
"id": 31,
"email": "ff#b.com",
"first_name": "ff",
"last_name": "ff",
"phone_number": "ff",
"shipping_address": "",
"coupon_code": "",
"gross_total": 1.0,
"payment_method": "ONLINE",
"order_status": "PLACED",
"created_at": "2016-10-01T17:26:00.432000",
"updated_at": "2016-10-01T17:48:50.797000",
"is_active": true,
"order_details": [
{
"coupons": {}
},
{
"coupons": {}
},
{
"coupons": {}
}
]
}
I think you should replace the inherited class with serializers.ModelSerializer in CouponSerializer and OrderDetailSerializer instead of just serializer.Serializer - just like you did in OrderSerializer.
After that you'll get some errors because your models (Coupon and OrderDetail) don't declare any of created_at, updated_at nor is_active fields. So you should add those fields to your models or remove them from the list in Meta in both serializer classes. But after that it works as expected.