Django Serialize multiple models in a single view - django

Here's the scenario, i have two models Offre and Recruteur
class Recruteur(models.Model):
[...]
entrepriseName = models.CharField(max_length=50)
[...]
class Offre(models.Model):
[...]
idRecruteur = models.ForeignKey(Recruteur,verbose_name = "idRecruteur", on_delete=models.CASCADE, default=None)
[...]
And I have the following serializers:
class RecruteurByIdSerializer(serializers.ModelSerializer):
class Meta:
model = Recruteur
fields = ( 'entrepriseName',)
class OffreSerializer(serializers.ModelSerializer):
recruteur = RecruteurByIdSerializer(many=True, read_only=True)
class Meta:
model = Offre
fields = ( 'title', 'dateAjout', 'description', 'recruteur')
i expected this result:
but im getting this instead:
what am i doing wrong ?

You have to provide source parameter as below,
class OffreSerializer(serializers.ModelSerializer):
entrepriseName = RecruteurByIdSerializer(source='idRecruteur', read_only=True)
class Meta:
model = Offre
fields = ('title', 'dateAjout', 'description', 'entrepriseName')

Related

How to fetch parent child hierarchy using django rest-framework

I am new to Django rest-framework. I am writing an API to fetch details in a parent-child hierarchy. Following is my code;
models.py
class ConfigAttributes(models.Model):
attr_set_name = models.CharField(max_length=32)
product_type = models.CharField(max_length=32)
class ProductInfo(models.Model):
config_attr = models.ForeignKey(ConfigAttributes, on_delete=models.CASCADE)
product_name = models.CharField(max_length=32)
class AttributeDetails(models.Model):
product_info = models.ForeignKey(ProductInfo, on_delete=models.CASCADE)
attribute_name = models.CharField(max_length=32)
serializers.py
class ConfigAttributesSerializer(serializers.ModelSerializer):
class Meta:
model = ConfigAttributes
fields = ['id', 'attr_set_name', 'product_type']
class ProductInfoSerializer(serializers.ModelSerializer):
class Meta:
model = ProductInfo
fields = ['id', 'product_name', 'config_attr_id']
class AttributeDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = AttributeDetails
fields = ['id', 'attribute_name', 'product_info_id']
views.py
class ConfigAttributesViewSet(viewsets.ModelViewSet):
queryset = ConfigAttributes.objects.all()
serializer_class = ConfigAttributesSerializer
class ProductInfoViewSet(viewsets.ModelViewSet):
queryset = ProductInfo.objects.all()
serializer_class = ProductInfoSerializer
class AttributeDetailsViewSet(viewsets.ModelViewSet):
queryset = AttributeDetails.objects.all()
serializer_class = AttributeDetailsSerializer
and app/urls.py
router = routers.DefaultRouter()
router.register('config', ConfigAttributesViewSet)
router.register('product', ProductInfoViewSet)
router.register('attr', AttributeDetailsViewSet)
urlpatterns = [
path('', include(router.urls)),
]
When I call the API, my required hierarchy and output is;
[
{
"attr_set_name" : "abc",
"product_type" : "efg",
"product_info" : {
"product_name" : "hij",
"attribute_details" : {
"attribute_name" : "klm"
}
}
}
]
What are the changes need to done in the files to get the above output in hierarchy (I am using Postman to check my APIs). Thank you for the help.
You can nest your serializers. To match your general API hierarchy this is as close as you can get. Unfortunately, the relationship fields will be lists.
class AttributeDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = AttributeDetails
fields = ['id', 'attribute_name', 'product_info_id']
class ProductInfoSerializer(serializers.ModelSerializer):
attribute_details = AttributeDetailsSerializer(many=True)
class Meta:
model = ProductInfo
fields = ['id', 'product_name', 'config_attr_id', 'attribute_details']
class ConfigAttributesSerializer(serializers.ModelSerializer):
product_infos = ProductInfoSerializer(many=True)
class Meta:
model = ConfigAttributes
fields = ['id', 'attr_set_name', 'product_type', 'product_infos']
You can get the specific parent elements if you start with the AttributeDetails instance though:
class ConfigAttributesSerializer(serializers.ModelSerializer):
class Meta:
model = ConfigAttributes
fields = ['id', 'attr_set_name', 'product_type',]
class ProductInfoSerializer(serializers.ModelSerializer):
config_attribute = ConfigAttributesSerializer(many=False)
class Meta:
model = ProductInfo
fields = ['id', 'product_name', 'config_attr_id', 'config_attribute']
class AttributeDetailsSerializer(serializers.ModelSerializer):
product_info = ProductInfoSerializer(many=False)
class Meta:
model = AttributeDetails
fields = ['id', 'attribute_name', 'product_info_id', 'product_info']

I want to Serialize dept_name as well as it's "id" in one single model serializer. How should I do it?

I want to serialize "Department name"(dept_name) as well as Department ID(id) in the Employee Model Serializer from department Model
In the Employee Serializer I want to Serialize "Department name" as well as "Dept ID" models. I mentioned Department Model in class Meta of Employee Serializer as well
MODELS
class Department(models.Model):
dept_name = models.CharField(max_length=10)
class Employee(models.Model):
emp_name = models.CharField(max_length=15)
email = models.EmailField(unique=True)
password = models.CharField(max_length=14)
designation = models.CharField(max_length=20)
dept_id = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
ordering = ('id',)
def __str__(self):
return self.emp_name
SERIALIZER
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Department
fields = [
'id',
'dept_name',
]
class EmployeeSerializer(serializers.ModelSerializer):
dept_id = serializers.SlugRelatedField(queryset=Department.objects.all(), slug_field='dept_name')
deptname = DepartmentSerializer()
class Meta:
model = Employee,Department
fields = [
'id',
'emp_name',
'email',
'password',
'designation',
'dept_id',
'deptname',
]
Remember to select_related('dept') on your Employee queryset.
class Department(models.Model):
dept_name = models.CharField(max_length=10)
class Employee(models.Model):
emp_name = models.CharField(max_length=15)
email = models.EmailField(unique=True)
password = models.CharField(max_length=14)
designation = models.CharField(max_length=20)
# .._id suffix django will implement automatically
dept = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
ordering = ('id',)
def __str__(self):
return self.emp_name
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Department
fields = ('id', 'dept_name')
class EmployeeSerializer(serializers.ModelSerializer):
dept = DepartmentSerializer()
class Meta:
model = Employee
fields = ('id',
'emp_name',
'email',
'password',
'designation',
'dept')
you can use depth in in EmployeeSerializer. It will return all department object's fields.
=================
depth = 1 => returns one level of depth.
depth = 2 => returns two levels of depth.
like this :
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Department
fields = '__all__'
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
depth = 1

How to serialize models with multiple foreign keys?

I want to serialize data in the format given below.I'm new to django-rest framework.I am working in a varsity project.So, little help will be appreciated.
{
{
"Series_name":"something",
"Home_team":"anything",
"Away_team":"sbh",
"players":[
{
"id":"1",
...
}
{
"id":"2",
...
}
]
},
{
"Series_name":"something2",
"Home_team":"anything",
"Away_team":"sbh",
"players":[
{
"id":"1",
...
}
{
"id":"1",
...
}
]
}
}
I have tried this.But this doesn't give satisfactory result.In fact it returns empty set.
class PlayersSerializer2(serializers.ModelSerializer):
class Meta:
model = Players
fields = ['name', 'country', 'image', 'role', 'credit']
class SeriesListSerializer2(serializers.ModelSerializer):
class Meta:
model = SeriesList
fields = '__all__'
class SeriesSquadsSerializer(serializers.ModelSerializer):
players = PlayersSerializer2(many=True, read_only=True)
series = SeriesListSerializer2(many=True, read_only=True)
class Meta:
model = SeriesSquads
fields = ['series', 'players']
these are the models I'm working with.I've 3 models SeriesList,Series_Squads and Players.Series_sqauds has unique pairs (Series_name,Players).It has two foreign keys pointing objects of SeriesList and Players.
class SeriesList(models.Model):
Series_name = models.CharField(max_length=250,
unique=True,primary_key=True)
No_of_matches = models.IntegerField()
Home_team = models.CharField(max_length=250)
Away_team = models.CharField(max_length=250)
class SeriesSquads(models.Model):
Series_name = models.ForeignKey(SeriesList, on_delete=models.CASCADE)
Squad_player = models.ForeignKey(Players, on_delete=models.CASCADE)
class Players(models.Model):
name = models.CharField(default="", max_length=250)
country = models.CharField(max_length=250)
image = models.CharField(max_length=500)
role = models.CharField(max_length=30)
credit = models.FloatField(default=None)
You can get user of SerializerMethodField to get your ForeignKey related objects into your serializer. Update your serializer so that:
class PlayersSerializer2(serializers.ModelSerializer):
class Meta:
model = Players
fields = ['name', 'country', 'image', 'role', 'credit']
class SeriesSquadsSerializer(serializers.ModelSerializer):
players = PlayersSerializer2(many=True, read_only=True)
Series_name = serializers.SerializerMethodField()
Home_team = serializers.SerializerMethodField()
Away_team = = serializers.SerializerMethodField()
class Meta:
model = SeriesSquads
fields = ['players']
def get_Series_name(self, obj):
return obj.Series_name.Series_name
def get_Home_team(self, obj):
return obj.Series_name.Home_team
def get_Away_team(self, obj):
return obj.Series_name.Away_team

Django Rest Framework get attributes from foreign key's class

here's my models:
class Recruteur(models.Model):
entrepriseName = models.CharField(max_length=50)
emplacement = models.CharField(max_length=50)
class Offre(models.Model):
title = models.CharField(max_length=100, blank=True, default=0)
idRecruteur = models.ForeignKey(Recruteur,verbose_name = "idRecruteur", on_delete=models.CASCADE, default=None)
and here's my api.py:
class VilleViewSet(ModelViewSet):
queryset = Offre.objects.values('idRecruteur__emplacement').distinct()
serializer_class = VilleSerializer
serializers.py:
class EmplacementSerializer(serializers.ModelSerializer):
class Meta:
model = Recruteur
fields = ('emplacement',)
class VilleSerializer(serializers.ModelSerializer):
emplacements = EmplacementSerializer(source='idRecruteur', read_only=True)
class Meta:
model = Offre
fields = ( 'emplacements',)
i was expecting a result like this
but i got nothing instead ..
Any ideas why?
You get nothing, because there is no emplacements field in Offre model. I guess, what you want is to get serialized Recruteur record, that is referenced by idRecruteur field. Try this:
class VilleSerializer(serializers.ModelSerializer):
idRecruteur = EmplacementSerializer(read_only=True)
class Meta:
model = Offre
fields = ( 'idRecruteur',)

Django. How to create django_easyselect_form with custom fieldset?

There is my model:
class MoneyTransfer(models.Model):
sender = models.ForeignKey(BankAccount, related_name='outcome_transfers')
receiver = models.ForeignKey(BankAccount, related_name='income_transfers')
when = models.DateTimeField()
total = models.FloatField()
comment = models.CharField(max_length=255)
objects = TransferQuerySet.as_manager()
form:
SendTransferForm = select2_modelform(MoneyTransfer)
I have two usages of form:
1. fields = 'receiver', 'comment', 'total'
2. fields = 'sender', 'receiver', 'comment', 'total'
How to implement it in code?
You can create two forms class
class FirstForm(ModelForm):
class META:
model = models.MoneyTransfer
fields = ['receiver', 'comment', 'total']
and then:
class SecondForm(ModelForm):
class META:
model = models.MoneyTransfer
fields = ['sender', 'receiver', 'comment', 'total']
I've decided not to use model form and created simple form with necessary widgets:
class SendTransferForm(forms.Form):
sender = forms.ModelChoiceField(queryset=BankAccount.objects.all(), widget=Select2(), label="Счёт отправителя")
receiver = forms.ModelChoiceField(queryset=BankAccount.objects.all(), widget=Select2(), label="Счёт получателя")
total = forms.CharField(widget=forms.TextInput(attrs={'class': 'select2fake'}), label="Сумма")
comment = forms.CharField(widget=forms.TextInput(attrs={'class': 'select2fake'}), label="Комментарий")