how to Serialize multiple objects in Django - python

I have 2 models for admin and member positions and I would like to get both of the models in one API call to fetch the data on my front end. How can I achieve this?
class ClinetAdminPosition(models.Model):
name = models.CharField(max_length=128, null=True)
company = models.ForeignKey(
to="Company", on_delete=models.CASCADE, related_name="admin_positions", null=True
)
modified_at = models.DateTimeField(verbose_name="Updated", auto_now=True, editable=True)
created_at = models.DateTimeField(verbose_name="Created", auto_now_add=True, editable=False)
def __str__(self):
return f"{self.name}"
class ClinetMangerPosition(models.Model):
name = models.CharField(max_length=128, null=True)
company = models.ForeignKey(
to="Company", on_delete=models.CASCADE, related_name="manger_positions", null=True
)
modified_at = models.DateTimeField(verbose_name="Updated", auto_now=True, editable=True)
created_at = models.DateTimeField(verbose_name="Created", auto_now_add=True, editable=False)
def __str__(self):
return f"{self.name}"
I want to get both models' data from 1 API request
to be like this:
[
{
"admin_positions": [
{
"name": "test",
"company": 1
},
{
"name": "test2",
"company": 1
},
{
"name": "test3",
"company": 1
}
],
"manger_position": [
{
"name": "test",
"company": 1
},
{
"name": "test2",
"company": 1
},
{
"name": "test3",
"company": 1
}
]
}
]

You can do something like this.
**This is your serializers classes **
class ClinetMangerPositionSerializer(ModelSerializer)
clas Meta:
model = ClinetMangerPosition
fields = ['name','company']
class ClinetAdminPositionSerializer(ModelSerializer):
class Meta:
model = ClinetAdminPosition
fields = ['name','company']
This will be your views class to display data.
from rest_framework.views import APIView
from . import serializers
from rest_framework.response import Response
class ViewName(APIView):
def get(self, request):
admin = ClinetAdminPosition.objects.all()
manager = ClinetMangerPosition.objects.all()
res :{
"admin_positions": serializers.ClinetAdminPositionSerializer(admin, many=True).data
"manager_positions":serializers.ClinetMangerPositionSerializer(manager, many-True).data
}
return Response(res)
something like this,

Let me know if you got any doubt
class ClinetMangerPositionSerializer(ModelSerializer)
clas Meta:
model = ClinetMangerPosition
fields = ['name','company']
class ClinetAdminPositionSerializer(ModelSerializer):
class Meta:
model = ClinetAdminPosition
fields = ['name','company']
class CompanySerializer(MOdelSerializer):
manger_position = ClinetAdminPositionSerializer(many=True,source
='clinetmangerposition')
admin_position = ClinetAdminPositionSerializer(many=True,source
='clinetadminposition')
class Meta:
model= Company
fields = ['manger_position','admin_position']

Related

How to set nested related fields serializers in Djando Rest Framework?

I'm using Django Rest Framework to build an API where I have the following models of Users making, confirming and showing interest on Events:
models.py
class User(AbstractBaseUser, PermissionsMixin):
user_name = models.CharField(_("user name"), max_length=150, unique=True)
slug = AutoSlugField(populate_from='user_name', unique=True)
class Event(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
owner = models.ForeignKey(User, related_name="owned_events", on_delete=models.SET_NULL, blank=True, null=True)
confirmed = models.ManyToManyField(User, related_name="confirmed_events", blank=True)
interested = models.ManyToManyField(User, related_name="interested_events", blank=True)
to serialize it I used the following code as I found here and at the DRF docs:
serializers.py
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = [
"url",
"user_name",
"password",
]
extra_kwargs = { "password": {"write_only": True} }
class EventSerializer(serializers.HyperlinkedModelSerializer):
owner = UserSerializer(required=False)
confirmed = UserSerializer(required=False, many=True)
interested = UserSerializer(required=False, many=True)
class Meta:
model = Event
lookup_field = 'slug'
extra_kwargs = { 'url': {'lookup_field': 'slug'} }
fields = [
"url",
"owner",
"name",
"confirmed",
"interested",
]
It works just fine like that, but I wanted the UserSerializer to show confirmed and interested events of each user just like each event shows the users confirmed and interested. I changed serializers and got the url of each event, like that:
serializers.py with HyperlinkedRelatedField on UserSerializer
class UserSerializer(serializers.HyperlinkedModelSerializer):
confirmed_events = serializers.HyperlinkedRelatedField(
queryset=Event.objects.all(),
view_name='event-detail',
lookup_field='slug',
many=True,
required=False
)
interested_events = serializers.HyperlinkedRelatedField(
queryset=Event.objects.all(),
view_name='event-detail',
lookup_field='slug',
many=True,
required=False
)
class Meta:
model = User
fields = [
"url",
"user_name",
"password",
"confirmed_events",
"interested_events",
]
extra_kwargs = { "password": {"write_only": True} }
This got me the following JSON from the User model:
{
"user_name": "d",
"confirmed_events": [],
"interested_events": [
"http://localhost:8000/events/eqwer-2/",
"http://localhost:8000/events/test/",
"http://localhost:8000/events/test-2/",
"http://localhost:8000/events/test-3/",
]
}
And from the Event model:
{
"url": "http://localhost:8000/events/eqwer-2/",
"owner": null,
"name": "eqwer",
"slug": "eqwer-2",
"confirmed": [],
"interested": [
{
"user_name": "d",
"confirmed_events": [],
"interested_events": [
"http://localhost:8000/events/eqwer-2/",
"http://localhost:8000/events/test/",
"http://localhost:8000/events/test-2/",
"http://localhost:8000/events/test-3/",
]
}
]
},
The Event model JSON is fine because it shows each user's data, but I wanted the User JSON to show each event data instead of just the event URL, it'd be something like:
{
"user_name": "d",
"confirmed_events": [],
"interested_events": [
{
"url": "http://localhost:8000/events/eqwer-2/",
"owner": null,
"name": "eqwer",
"slug": "eqwer-2",
},
]
}
Create a separate serializer for interested_events like so:
class InterestedEventsSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
fields = ('url', 'owner', 'name', 'slug')
And in your UserSerializer declare the interested_events using the serializer above:
class UserSerializer(serializers.HyperlinkedModelSerializer):
confirmed_events = ... #
interested_events = InterestedEventsSerializer(many=True)
class Meta:
model = User
fields = [
"url",
"user_name",
"password",
"confirmed_events",
"interested_events",
]
extra_kwargs = { "password": {"write_only": True} }

Django Serializer's Source argument is not working

I am trying to get all the bills and their customer-related details (i.e. 'customer_code', 'email' etc.) with it.
However, source='user.customer_code does not seem to have any effect at all. What am I missing?
I have been following along this:
this stackoverflow post with no luck.
My two models:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(db_index=True, unique=True, max_length=200)
customer_code = models.CharField(max_length=300, blank=True, null=True, default=None)
class Bill(models.Model):
customer = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True, related_name="customer_bill"
)
payable_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
View:
class BillView(APIView):
def get(self, request, format=None):
q = Bill.objects.all().select_related('customer')
s = BillSerializer(q, many=True)
return JsonResponse({
"bill": s.data
})
Serializer:
class BillSerializer(serializers.ModelSerializer):
customer_code = serializers.CharField(source='user.customer_code', read_only=True)
class Meta:
model = Bill
fields = ('id','payable_amount','customer_code') # binding customer_code here
Current Output:
"bill": [
{
"id": 1,
"payable_amount": "1000.00"
},
{
"id": 2,
"payable_amount": "2000.00"
}
]
Expected Result:
"bill": [
{
"id": 1,
"payable_amount": "1000.00",
"customer_code": "CUS10001" # want this to be attached
},
{
"id": 2,
"payable_amount": "2000.00",
"customer_code": "CUS10002" # want this to be attached
}
]

PUT on ModelViewSet with nested object Django Rest Framework

I'm building an API with the django rest framework. I have these models:
class Organism(models.Model):
name = models.CharField(max_length=255)
address = models.ForeignKey(Address, on_delete=models.CASCADE)
type = models.ForeignKey(Type, on_delete=models.CASCADE)
class Address(models.Model):
street = models.CharField(max_length=255, blank=True)
class Type(models.Model):
name = models.CharField(max_length=255, blank=True)
This is the view for my mode Organism :
class OrganismViewSet(viewsets.ModelViewSet):
queryset = Organism.objects.all()
serializer_class = OrganismSerializer
pagination_class = StandardResultsSetPagination
filter_backends = (filters.SearchFilter, DjangoFilterBackend)
filter_class = OrganismFilter
search_fields = ('name')
And my serializer:
class OrganismSerializer(serializers.ModelSerializer):
addresse = AddressSerializer()
type = TypeSerializer()
class Meta:
model = Organism
fields = '__all__'
def update(self, instance, validated_data):
// What I should write to do something "elegant"
Let's imagine when I get my Organism, I have:
{
"address": {
"id": 1
"street": "test"
},
type: {
"id": 1,
"name": "type Organism"
},
"name":"TestTest",
}
So I'm trying to update an Organism (I want to change the name of the street but not create a new object AND change the Type which exists in my database) by sending this:
{
"address": {
"id": 1
"street": "new name"
},
type: {
"id": 2,
"name": "new type"
}
"name":"TestTest",
}
And the fact is I don't have the ID of my object in the parameter "validated_data" of the method update.
If you guys know how to proceed... Thank you in advance.

Django Rest Framework foreign key nesting

I am trying to nest my Users table inside my Relationships table. So instead of this:
[
{
"user": 1,
"related_user": 2,
"relationship": "followed_by"
}
]
I am trying to get this:
[
{
"user": {
"username": "user1",
"name": "User 1",
"email": "bla",
"phone": "bla",
"date_joined": "2017-11-01T21:34:13.101256Z"
},
"related_user": {
"username": "user2",
"name": "User 2",
"email": "bla",
"phone": "bla",
"date_joined": "2017-11-01T21:34:13.101256Z"
},
"relationship": "followed_by"
}
]
I looked up tutorials and I tried adding serializers.RelatedField , UserSerializer(many=true, read-only=true) etc. but nothing worked
Models.py
class User(models.Model):
username = models.CharField(max_length=255)
name = models.CharField(max_length=255)
email = models.CharField(max_length=255)
phone = models.CharField(max_length=255)
date_joined = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self):
return str(self.pk) + ", " + self.username
RELATIONSHIP_CHOICE = [
("follows", "follows"),
("followed_by", "followed_by"),
("none", "none"),
]
class Relationship(models.Model):
user = models.ForeignKey(User, related_name="primary_user", null=True)
related_user = models.ForeignKey(User, related_name="related_user", null=True)
relationship = models.CharField(max_length=40, choices=RELATIONSHIP_CHOICE, default=RELATIONSHIP_CHOICE[0])
Serializers.py
from rest_framework import serializers
from . import models
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = models.User
fields = (
'username',
'name',
'email',
'phone',
'date_joined',
)
class RelationshipSerializer(serializers.ModelSerializer):
related_user = UserSerializer(many=True)
class Meta:
model = models.Relationship
fields = (
'user',
'related_user',
'relationship',
'related_user'
)
I tried to add related user to my serializer but it didnt work. I am getting an error: 'User' object is not iterable
Any help is appreciated.
class RelationshipSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
related_user = UserSerializer(read_only=True)
class Meta:
model = models.Relationship
fields = (
'user',
'related_user',
'relationship'
)
user = UserSerializer(read_only=True, many=True) is for manytomany field,user = UserSerializer(read_only=True) is for ForeignKey field.

Allow to post json with array of jsonobjects inside

I am a newbie in django world and I'm trying to create a simple rest service with those models:
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician,on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
And those serializers:
class MusicianSerializer(serializers.ModelSerializer):
class Meta:
model = Musician
fields = ('id','first_name', 'last_name', 'instrument')
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
model = Album
fields = ('id','artist', 'name', 'release_date', 'num_stars')
I want to be able to post a JSON like this one:
{
"first_name": "MusicNom",
"last_name": "MusicCognom",
"instrument": "Flauta",
"albums":
[
{
"name": "Album1",
"release_date": "2015-02-12",
"num_stars": 5
},
{
"id": 2,
"artist": 1,
"name": "AlbumNuevo",
"release_date": "2013-01-08",
"num_stars": 5
}
]
}
This JSON should create the musician and his albums. I've found some examples in the documentation that are useful using "GET" but I would like to do it with "POST".

Categories