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.
Related
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')
I have a number of different models connected to the User model through a foregin key relationship. I would now like to display all the attributes from the objects connected to the User model in the main admin overview.
models.py
class User(AbstractBaseUser):
username = models.CharField(max_length=60)
lastname = models.CharField(max_length=60, blank=True)
class UserProfile(models.Model):
user_id = models.OneToOneField(
User,
on_delete=models.CASCADE,
primary_key=True,
)
address = models.CharField(max_length=60, blank=True)
admin.py
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('user_firstname', 'user_lastname', 'address')
def user_firstname(self, instance):
return instance.user_id.username
def user_lastname(self, instance):
return instance.user_id.lastname
admin.site.register(UserProfile, UserProfileAdmin)
The code above works perfectly well to display attributes from "User" in "Userprofile", but how do I do this the other way around? In my code I currently have 4 different objects connected to the User object so keen to find a way to display all the data there.
use inlines
models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
admin.py
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
more info read https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#inlinemodeladmin-objects
How to save array of values in django rest framework ,can you help to solve this problem.
example:
{
"user":test{
"category":cat1,
"subcategories":sub1
},
{
"category":cat2,
"subcategories":sub2
}
}
models.py
class SavingCategoryandPreferences(models.Model):
user = models.ForeignKey(User, related_name='user')
category = models.ForeignKey(Category)
subcategories= models.ForeignKey(SubCategory, related_name='sub', default=1)
sort_order = models.IntegerField(default=0)
slug = AutoSlugField(populate_from='subcategories_id', separator='', editable=True)
created_time = models.DateTimeField("Created Date", auto_now_add=True)
serializer.py
class SavecatsubSerialize(serializers.ModelSerializer):
class Meta:
model = SavingCategoryandPreferences
fields = ('id', 'user', 'category', 'subcategories')
views.py
class Mobilesavecatsub(viewsets.ModelViewSet):
serializer_class = serializers.SavecatsubSerialize
queryset = SavingCategoryandPreferences.objects.all()
There are multiple approaches to this problem:
If you're just saving the data and do not want to process it in your application, the simplest method is just stringifying the dictionary (json.dumps is a good option) and saving the string as a TextField with a large max_length. Not recommended if you want to query results from the stringified dictionary.
If you want to query the saved data, the ideal way is to create multiple models for your internal fields and link them via a ForeignKey to your base model. Example:
class User(models.Model):
name = models.CharField(max_length=20)
class Category (models.Model):
name = models.CharField(max_length=20)
user = models.ForeignKey(User)
class Subcategory (models.Model):
name = models.CharField(max_length=20)
category = models.ForeignKey(Category)
I want get college data using general_info foreign key. without making nested serializer of college_set in GeneralInfo serializer. Is there any alternative in django rest framework or is not possible? I have tried above below line of code but its not working. is there any other way?
college = serializers.CharField(source='general_info.college_set', read_only=True)
models.py
from django.db import models
class GeneralInfo(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
address = models.CharField(max_length=30)
class Student(models.Model):
general_info = models.ForeignKey(to=GeneralInfo, on_delete=models.PROTECT)
course = models.CharField(max_length=30)
marks = models.CharField(max_length=30)
class College(models.Model):
general_info = models.OneToOneField(to=GeneralInfo, on_delete=models.PROTECT)
name = models.CharField(max_length=30)
address = models.CharField(max_length=30)
picture = models.ImageField(null=True, blank=True, upload_to='users/')
serializer.py
from rest_framework import serializers
class MySerializer(serializers.ModelSerializer):
name = serializers.CharField(source='general_info.first_name', read_only=True)
college = serializers.CharField(source='general_info.college_set', read_only=True)
class Meta:
model = Student
fields = ('name', 'college')
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.