So I'm working on Django back-end and React front-end. I have a many-to-many field in one of my models, and trying to serialize.
I've googled some related issues and tried things out, but none worked.
Let me show you my code first.
models.py
class Category(models.Model):
objects = models.Manager
category = models.CharField(max_length = 20)
class Content(models.Model):
objects = models.Manager()
title = models.CharField(max_length = 100, null=True)
category = models.ManyToManyField(Category)
serializers.py
class ContentSerializer(serializers.ModelSerializer):
category_name = serializers.SerializerMethodField()
class Meta:
model = Content
fields = [
'title', 'category_name'
]
def get_category_name(self, obj):
categories = self.context['book'].category.all()
return categories
Finally, views.py
#api_view(['GET'])
def each_book(request, pk):
this_book = Content.objects.get(pk=pk)
serialized = ContentSerializer(
this_book,
context={
'request':request,
'book' : this_book
},
)
return Response(serialized.data)
I keep on getting error saying Object of type Category is not JSON serializable. What do you think is the problem? Thanks a lot in advance. :)
---- LATEST CODE
models.py
class Category(models.Model):
category = models.CharField(max_length = 20)
class Content(models.Model):
title = models.CharField(max_length = 100, null=True)
category = models.ManyToManyField(Category)
serializers.py
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['category']
class ContentSerializer(serializers.ModelSerializer):
category_name = CategorySerializer(many=True)
class Meta:
model = Content
fields = [
'category_name'
]
Related
i am working on ecommerce shop and in my home page i want to return all the products and 7 images for the icons for the categories , my models.py is
class Product(models.Model):
pub_date = models.DateTimeField(default=datetime.now)
price = models.DecimalField(max_digits=100,decimal_places=2,null=False,blank=False)
category = models.CharField(max_length=20 ,blank=False, null=False ,default='none', choices=cat)
product_name = models.CharField(max_length = 50, null=True)
photo = models.ImageField(upload_to = 'product_photos/%y/%m/%d',null=True)
class Category(models.Model):
icon = models.ImageField(upload_to = 'icon',null=True)
and my serializers.py is
class ProductSerializer (serializers.ModelSerializer):
class Meta :
model = Product
fields = '__all__'
class CategorySerializer (serializers.ModelSerializer):
class Meta :
model = Category
fields = '__all__'
and my views.py
#api_view(['GET'])
#permission_classes ([AllowAny] , )
def home (request):
p = Product.objects.filter(is_discount= 1).order_by('-pub_date')
serializer = ProductSerializer(p,many=True)
return Response (serializer.data)
how to return both the category and product in the same view , NOTE : my views.py is function based view
I want to access verbose name of models to put it as a key in serializer. But I can't find a way to do it.
My models are:
class ProductCategory(models.Model):
name = models.CharField(max_length=150, unique=True)
created_at = models.DateTimeField(default=timezone.now)
modified_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
class DeviceTypeCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE,
related_name="device_types")
class Meta:
verbose_name = _("Device type")
verbose_name_plural = _("Device types")
class DeviceBrandCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE,
related_name="device_brands")
class PartTypeCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, related_name="part_types")
And my serializer:
class ProductCategorySerializer(serializers.ModelSerializer):
device_types = serializers.StringRelatedField(many=True)
device_brands = serializers.StringRelatedField(many=True)
part_types = serializers.StringRelatedField(many=True)
class Meta:
model = ProductCategory
fields = ('name', 'device_types', 'device_brands', 'part_types')
Any suggestions would help. I would also be glad to hear out other ideas on how to create categories model. I've tried django-mptt, but I need product to belong to multiple subcategories. The django-polymorphic-mptt could have help. But I couldn't find proper documentation.
You can do something like the following:
class ProductCategorySerializer(serializers.ModelSerializer):
device_types = serializers.StringRelatedField(many=True)
device_brands = serializers.StringRelatedField(many=True)
part_types = serializers.StringRelatedField(many=True)
plural_name = serializers.SerializerMethodField()
def get_plural_name(self, obj):
return ProductCategory._meta.verbose_name_plural
class Meta:
model = ProductCategory
fields = ('name', 'device_types', 'device_brands', 'part_types', 'plural_name')
this is my models
class Users(models.Model) :
name = models.CharField(max_length=20 , blank=False , null=False)
email = models.EmailField(max_length=50 , blank=True , null=True)
password = models.CharField(max_length=30 , blank=False , null=False)
birthday = models.DateField(null=False)
photo = models.ImageField(upload_to = 'user_photos/%y/%m/%d')
#friend = models.ManyToManyField('self',through='Notif',null=True,related_name='friend')
class Product(models.Model):
pub_date = models.DateTimeField(default=datetime.now)
price = models.DecimalField(max_digits=100000,decimal_places=5,null=False,blank=False)
size = models.IntegerField(null=True,blank=True,default='undefined')
photo = models.ImageField(upload_to = 'product_photos/%y/%m/%d',null=True)
#for 1--n relation with users
user_id = models.ForeignKey(Users,on_delete=models.CASCADE,null=True,related_name='user')
this is my serializers.py
class ProductSerializer (serializers.ModelSerializer):
class Meta :
model = Product
fields = '__all__'
class UsersSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = '__all__'
i want to send product object with the email of his user
what i have to do in serializers and views to make it
note i use function based views in my views
First of all, you should change user_id to user.
in serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = ['id','email']
class ProductSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta :
model = Product
fields = '__all__'
in function based views:
def get_product(request,product_id):
instance = Product.objects.select_related('user').get(id=product_id)
serializer = ProductSerializer(instance)
return Response(serializer.data)
NOTE: select_related is used to get product with user at the same query (join query).
So I'm using Django and have a foreignkey field. Let me show you the model first.
class Book(models.Model):
objects = models.Manager()
title = models.CharField(max_length = 30)
author = models.CharField(max_length = 20)
class Content(models.Model):
objects = models.Manager()
source = models.ForeignKey("Book", related_name='book', on_delete=models.CASCADE)
key_line = models.CharField(max_length = 100, null=True)
I used serializer to load the api to my React front end. But then, the source field is displayed as integer, which probably is the id of Book model.
However what I want to do is load the title of each book in the source field.
Any advice?
FYI, other codes.
views.py
#api_view(['GET'])
def each_book(request, pk):
this_book = Content.objects.get(pk=pk)
serialized = ContentSerializer(this_book, context={'request':request})
return Response(serialized.data)
serializers.py
class ContentSerializer(serializers.ModelSerializer):
class Meta:
model = Content
fields = '__all__'
You could just pass book to the context field and call it like:
#api_view(['GET'])
def each_book(request, pk):
this_book = Content.objects.get(pk=pk)
serialized = ContentSerializer(this_book, context={'request':request, 'book': this_book})
return Response(serialized.data)
Then
class ContentSerializer(serializers.ModelSerializer):
book_title = serializers.SerializerMethodField()
class Meta:
model = Content
fields = '__all__'
def get_book_title(self, obj): # Note that obj is `content` in this case.
return self.context['book'].title
Make sure you include it in your fields too. Not sure if it works with __all__. If it doesn't, then just explicitly write all your fields out with the book_title field included.
Before this gets marked as a duplicate, I've looked at the following questions:
Django Rest framework Serialize many to many field
Django rest framework serializing many to many field
No results are being shown for payins when I test.
serializers.py
class PayinsSerializer(serializers.ModelSerializer):
class Meta:
model = Payins
fields = '__all__'
class UserStokvelSerializer(serializers.ModelSerializer):
payins = PayinsSerializer(many=True)
class Meta:
model = Stokvel
fields = '__all__'
models.py
class Payins(models.Model):
payin_date = models.DateField(default=timezone.now)
payin_by = models.ForeignKey(User, on_delete=models.CASCADE)
stokvel_payin = models.ForeignKey('Stokvel', on_delete=models.CASCADE, related_name="payin_user")
payin_amount = models.IntegerField()
def save(self, *args, **kwargs):
stokvel = Stokvel.objects.get(id = self.stokvel_payin.id)
stokvel.balance += self.payin_amount
stokvel.save()
super(Payins, self).save(*args, **kwargs)
class Stokvel(models.Model):
stokvel_name = models.CharField(max_length=55)
balance = models.IntegerField(default = 0)
payouts = models.ManyToManyField(Payouts, related_name="stokvel_payouts")
payins = models.ManyToManyField(Payins, related_name="stokvel_payins")
group_admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name="stokvel_group_admin")
users = models.ManyToManyField(User, related_name="stokvel_users")
invite_key = models.CharField(default = secrets.token_hex(15), max_length=55)
Was able to figure it out using this guide:
By modifying this example:
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ('order', 'title')
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')