How to create nested serialization from mutliple models uisng django rest framewrok - python

I am trying to create nested relationship from more than two models in Django Rest Framework.
Thank you in advance for helping me.
I succeed with two models but when I'm trying with three models unable to create nested serialization.
from django.db import models
class Project(models.Model):
project_id = models.AutoField(primary_key=True)
project_name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Site(models.Model):
site_id = models.AutoField(primary_key=True)
site_name = models.CharField(max_length=255)
project_id= models.ForeignKey(Project, related_name="projectid", on_delete=models.CASCADE)
def __str__(self):
return self.site_name
class Aggin(models.Model):
assign_id = models.AutoField(primary_key=True)
site_id = Models.ForeginKey(Site, relate_name="siteid", on_delete=models.CASCADE)
from rest_framework import serializers
from .models import Song, Artist
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ('__all__')
class SiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
fields = ('__all__')
class AggignSerializer(serializers.ModelSerializer)
class Meta:
model = Aggin
fields = ('__all__')

I think you don't need to primary id field if you wanna use the Django's default foreign key setting. And related_name should be defined from the view of the counterpart model.
from django.db import models
class Project(models.Model):
project_name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Site(models.Model):
site_name = models.CharField(max_length=255)
project = models.ForeignKey(Project, related_name="sites", on_delete=models.CASCADE)
def __str__(self):
return self.site_name
class Aggin(models.Model):
site = Models.ForeginKey(Site, relate_name="assigns", on_delete=models.CASCADE)
And then, in serializer, you can set like the following.
from rest_framework import serializers
from .models import Song, Artist
class ProjectSerializer(serializers.ModelSerializer):
sites = SiteSerializer(read_only = True, many = True)
class Meta:
model = Project
fields = ('id', 'project_name', 'sites')
class SiteSerializer(serializers.ModelSerializer):
assigns = AggignSerializer(read_only = True, many = True)
class Meta:
model = Site
fields = ('id', 'site_name', 'assigns')
class AggignSerializer(serializers.ModelSerializer):
class Meta:
model = Aggin
fields = ('id')

Related

Django Rest Framework - Create object with foregin key relation

I created simple REST API which i want to create product objects. My problem is that API view is not showing me multiple choice field to choose from existing categories.
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Product(models.Model):
name = models.CharField(max_length=200, unique=True)
price = models.PositiveSmallIntegerField(default="")
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, default=None)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
serializers.py
from rest_framework import serializers
from .models import Product, Category
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
views.py
from django.shortcuts import render
from django.http import HttpResponse
from rest_framework import viewsets
from .models import Product, Category
from .serilaizers import ProductSerializer, CategorySerializer
from rest_framework.response import Response
from rest_framework.views import APIView
class ProductView(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
class CategoryView(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
That is what i get after running server, only two positions:
__all__ does not work with ForeignKey and other relationship fields. You need to specify the field names explicitly. Add a list or tuple with field names to your ProductSerializer.
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ("name", "price", "category")

Foreign Key with Django REST Serializers

I'm having trouble figuring out how to get the Foreign key relationship to work with my Django REST api.
I have a model
from django.db import models
from django.core.validators import RegexValidator
# Create your models here.
class Hero(models.Model):
alphanumeric = RegexValidator(r'^[0-9a-zA-Z]*$', 'Only alphanumeric characters are allowed.')
name = models.CharField(max_length=60, blank=True, validators=[alphanumeric])
alias = models.CharField(max_length=60)
def __str__(self):
return self.name
class SideKick(models.Model):
alphanumeric = RegexValidator(r'^[0-9a-zA-Z]*$', 'Only alphanumeric characters are allowed.')
hero = models.ForeignKey(Hero, related_name='sidekicks', on_delete=models.CASCADE)
sideKick_name = models.CharField(max_length=60, validators=[alphanumeric])
def __str__(self):
return self.sideKick_name
Serializers
from rest_framework import serializers
from .models import Hero, SideKick
class HeroSerializer(serializers.HyperlinkedModelSerializer):
sidekicks = serializers.SlugRelatedField(many=True, read_only=True, slug_field='title')
class Meta:
model = Hero
fields = ('name', 'alias', 'sidekicks')
class SideKickSerializer(serializers.HyperlinkedModelSerializer):
sideKick_name = HeroSerializer()
class Meta:
model = SideKick
fields = ('sideKick_name')
Here is what the api webpage looks like
I'm fairly new to this and was wondering how I can get the option to select a Hero to create a sidekick through the API webpage.
every time i create a hero the sidekick field is blank.
Any help would be apperciated.
Try somthing like this :
class HeroSerializer(serializers.HyperlinkedModelSerializer):
sidekicks = serializers.SerializerMethodField()
class Meta:
model = Hero
fields = ('name', 'alias', 'sidekicks')
def get_sidekicks(self, obj):
sidekicks = []
SideKick_objects = SideKick.objects.all()
for f in SideKick_objects:
features.append({"alphanumeric": f.alphanumeric, "hero": f.hero, "sideKick_name": f.sideKick_name})
return sidekicks
If you get any error for "sidekicks = serializers.SerializerMethodField()"
try using : "serializers.ModelSerializer" instead "serializers.HyperlinkedModelSerializer"

Django Forms created from Model with overfull Queryset Output

I am trying to create a ModelForm for my Model Class "Asset" in Django 3
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class Manufacturer(models.Model):
name = models.CharField(max_length=100)
class Asset(models.Model):
serial = models.CharField(max_length=200)
manufacturer = models.ManyToManyField(Manufacturer)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
I managed to create a Form via the following code
from django import forms
from .models import Manufacturer
class AssetForm(forms.Form):
serial = forms.CharField(max_length=150)
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all().values('name'))
name = forms.CharField(max_length=200)
description = forms.TextInput()
status = forms.CharField(max_length=200)
category = forms.CharField(max_length=200)
The querySet results in a dropdown being filled out with either "{'name':'Apple'}" or "('Apple',)" depending on using values or values_list respectively. How can I just display the name itself?
Adding the following method to the model fixes the problem:
def __str__(self):
return self.name
This will return the name and only the name to the queryset.

Can't to add a data into MongoDB using djongo "Array Model Field"

I'm trying to add a data using "Array Model Field"(djongo) as shown Djongo Documentation(Array Model Field) or
from djongo import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
class Meta:
abstract = True
class MetaData(models.Model):
pub_date = models.DateField()
mod_date = models.DateField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
class Meta:
abstract = True
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
class Meta:
abstract = True
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.EmbeddedModelField(
model_container=Blog,
)
meta_data = models.EmbeddedModelField(
model_container=MetaData,
)
headline = models.CharField(max_length=255)
body_text = models.TextField()
authors = models.ArrayModelField(
model_container=Author,
)
n_comments = models.IntegerField()
def __str__(self):
return self.headline
Into admin.py I added for registration of model in admin panel
from django.contrib import admin
from .models import Entry
admin.site.register(Entry)
And when I try to add a data via http://localhost:8000/admin/ I have a MigrationError...
Where is my mistake? And what am I not understanding?
You should use models.ObjectIdField() on all models to avoid calling django migrations.
Example:
class Author(models.Model):
_id = models.ObjectIdField()
name = models.CharField(max_length=200)
email = models.EmailField()
class Meta:
abstract = True
def __str__(self):
return self.name
See more in Djongo Docs
I'm a stupid. Sry. I didn't 'makemigration' after update a model.
And so here's what I did to make it work:
1. After update a model I did 'python manage.py makemigrations' and that power on.

Dynamic choices in Foreignkey Field in Django Rest Framework

I have just started learning Django Rest Framework and trying to make a simple API using Django rest Framework.
This is my models.py
from __future__ import unicode_literals
from django.db import models
class Student(models.Model):
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=150, blank=False)
student_id = models.CharField(max_length=20, primary_key=True)
father_name = models.CharField(max_length=150)
mother_name = models.CharField(max_length=150)
class Meta:
ordering = ('student_id',)
class Subject(models.Model):
created = models.DateTimeField(auto_now_add=True)
subject_id = models.CharField(max_length=20, primary_key=True)
name = models.CharField(max_length=150)
class Meta:
ordering = ('subject_id',)
class Result(models.Model):
created = models.DateTimeField(auto_now_add=True)
grade = models.DecimalField(max_digits=5, decimal_places=3, blank=False)
student_id = models.ForeignKey(Student, on_delete=models.CASCADE)
subject_id = models.ForeignKey(Subject, on_delete=models.CASCADE)
class Meta:
ordering = ('created',)
And this is my serializers.py
from rest_framework import serializers
from models import *
class StudentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Student
fields = ('student_id', 'name', 'father_name', 'mother_name')
class SubjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Subject
fields = ('subject_id', 'name')
class ResultSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Result
fields = ('grade', 'student_id', 'subject_id')
In my "Result" model, I have two foreign keys; student_id and subject_id. This is how it looks like:
My questions is, how can I show the "name" field in the drop down menu in stead of showing "Student Object" and "Subject Object"?
I have tried with
STUDENT_CHOICES = [(each.student_id, each.name) for each in Student.objects.all()]
SUBJECT_CHOICES = [(each.subject_id, each.name) for each in Subject.objects.all()]
in the model's "choices=" field but it didn't work out.
Thanks in advance.
I think you're looking for this part of the DRF documentation.
Basically, your Django model's own representation is used. So for example, in your Student model you can add __str__ method:
# this is for Python 3, use __unicode__ on Python 2
def __str__(self):
return self.name
Meta options documentation for Django is here, look for model methods.

Categories