what is related_name and related_query_name in django? - django

i have an issue with the code in django framework regarding to related_name and related_query_name in django. please django expert explain the related_name in django, the code is below:
related_name='+'

Related Name
Django maintains backward relation on each object for easy access to related objects. Suppose you have two models named "School" and "Student" and one school can have multiple students. So you will have model definition something like this
class School(models.Model):
name = models.CharField(max_length=55)
city = models.Charfield(max_length=55)
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School)
Now if you have an school objects then you can access all students of that school with writing query explictly.
school = School.objects.get(id=1)
# Now if need all students of this school, first thing that come in your mind would be
Student.objects.filter(school=school)
# But instead of this, you can access all students by
school.student_set.all()
Here student_set is the default, related name made by Django. But you can have your custom related names like this
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School, related_name='students')
# Now you can do
school.students.all()
Special Character in related name
If you define related_name='+' then backward relation would not be available on object and school.student_set.all() will give you error.
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'. For example, this will ensure that the User model won’t have a backwards relation to this model:
Related Query Name
related_query_name is similar to related_name but it gets used in queryset.
If you need to apply some filter on student via school model, then you would do
School.objects.filter(student__name='abc')
But if you define related_query_name then you can do
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School, related_query_name='abc')
# Now you can do
School.objects.filter(abc__name='abc')
Refer doc for further reference: https://docs.djangoproject.com/en/3.0/ref/models/fields/

Related

Where to add Many to Many in django?

So, Am creating a app where user can add universities to their fav or wishlist ! The problem is, am just confused how and where add ManyToMany ?
Model Student:
name = models.CharField
.....
Model University:
name = models.CharField
.....
Model Wishlist:
wish = models.ManyToMany(University)
Is this correct, is it okay to create a seprate model class as "wishlist" or can i have the wishlist on the Student:
Am totally confused, all i need to do is "user needs to able to click heart button and add university to wishlist and if they reclicks it needs to removed"
If a Student can only have one wishlist, it makes no sense to define an extra model with a ManyToManyField. This would result in creating an extra table, and thus make queries less effective, and programs less readable.
In that case, you can define a ManyToManyField from your Student to the University, so:
class Student(models.Model):
name = models.CharField(max_length=128)
wishlist = models.ManyToManyField('University', blank=True)
# ⋮
class University(models.Model):
name = models.CharField(max_length=128)

How to expand application to work with multiple users and seasons

Let's say that I have created an app for a school with several models (e.g. Student, Teacher, Course, Attendance, Grade, Timetable, Payments etc).
It's working great for the current year. But now I want to expand my application, so that several schools can use it and it can store data of (mostly) independent seasons/years.
The first solution that comes to my mind, is to add 2 extra models (1)school=user and (2)season=year. And then add ForeignKeys from (almost) ALL my models to both of these (school, season).
(Maybe I could add a third model named SchoolSeason, with just these 2 fields and use this as FK to all my fields.)
Is there a more elegant solution?
Edit: a drawback to this solution would be that the models (e.g. Students) will share their auto-incremented ID with other schools.
Hard to tell without your current models but I would to the same by adding to 2 extra models. But no need to add both of them to all of your models : only Season is needed if you link Season to School.
class School(models.Model):
name = models.CharField(...)
class Season(models.Model):
school = models.ForeignKey(School)
name = models.CharField(...)
other_fields...
Each Season is linked to a School. Then, you can add the Foreign Key to all of your models.
About your problem in the edit, you are right, it would be a problem. You should not use auto-incremented key but UUid.
Finally, it would look like :
class BaseSeasonModel(models.Model):
uid = models.UUIDField(
primary_key=True,
default=uuid_lib.uuid4,
editable=False,
)
season = models.ForeignKey(Season)
class Meta:
abstract = True
And all of your models would inherit from it :
class Student(BaseSeasonModel):
...

Django complex models and Nested Queries

How to write a complex query to
1) create a student,Course,OptionOne - example -
student_name=John,
rollno = 20
course1 = this field will refence a field in OptionOne, OptionOne will
reference the course desired. enter code here
**illustration** - John Selects mathematics as the first option, while Mike
selects Geoography as Option One, Mathematics as Option Two
2) Select all students who opt mathematics as option one
3) Select the student alongwith the course he opted
django.db import models
# Create your models here.
class Course(models.Model):
course_name = models.CharField(max_length=200)
course_code = models.CharField(max_length=200)
class PriorityOne(models.Model):
course = models.OneToOneField(Course, verbose_name=("Course"),
on_delete=models.CASCADE)
class PriorityTwo(models.Model):
course = models.OneToOneField(Course, verbose_name=("Course"),
on_delete=models.CASCADE)
class PriorityThree(models.Model):
course = models.OneToOneField(Course, verbose_name=("Course"),
on_delete=models.CASCADE)
class Student(models.Model):
student_name=models.CharField(max_length=200)
rollno = models.CharField(max_length=200)
course1 = models.OneToOneField(PriorityOne,on_delete=models.CASCADE)
course2 = models.OneToOneField(PriorityTwo,on_delete=models.CASCADE)
course3 = models.ForeignKey(PriorityThree, on_delete=models.CASCADE)
You can use a M:M field here if multiple students can take the same course. The course will have the ManyToMany field referencing the Student model. This means multiple course objects can be associated with a student and a Student can have multiple Courses. I know it seems a little weird on where you define the M2M field. If you want to set a priority list, then you can define an integer field with the top priority course pk. That is of course one way of doing it. Any of the syntax for M2M fields are here Django M2M docs. If you need further explanation, I will be glad to help.

Authentication of different types of user of same name in django?

I have a model of teacher and student . If I created a Student and again create a teacher with same name and email and stuffs, It gets created .. Can't be a teacher and student of same people in a college. How to apply in rest api?
There are several way to solve this, depending on your requirements and preference.
One way would be at database level with constraints. In this case you'd have to create model with all people regardless of their status and add additional boolean field that differentiates between Students and Teachers. This would look like this:
class People(models.Model):
email = models.EmailField(unique=True)
is_teacher = models.BooleanField()
unique means that email must be unique throughout the table and if you try to add another person with the same email, IntegrityError will be raised.
There is also a possibility to use unique over several fields with unique_together like this.
class People(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
unique_together = (('first_name', 'last_name'),)
This means that first_name and last_name together must be unique.
Another approach would be to check if student or teacher is already in one or the other table before saving with filter() and exists().
teacher_exists = Teacher.objects.filter(teacher=something).exists()
student_exists = Teacher.objects.filter(student=something).exists()
exists() returns True if the QuerySet contains any results, and False if not.

How to use django ORM for dynamic binding relation?

Well, this is the problem, I have a username column and I defined it in the models.py.
And a user may take some courses( the course may changes in the future), the relation between user and courses is 1 vs multi, which means a user can take multi courses and a courses could be taken by several users.
I am new to django and DB design, how to represent this in Django with ORM?
def user(models.Model):
name = models.CharField(max_length=30)
class courses(models.Model):
course = models.CharField(max_length=100)
Following #djsutho thought, define a many-to-many relationship:
class user(models.Model):
name = models.CharField(max_length=30)
courses = models.ManyToManyField(courses)
class courses(models.Model):
course = models.CharField(max_length=100)
Then, for example, querying courses per user would be as easy as:
courses.objects.filter(user__name='Bob')
Also note that, by Django model naming convention, model class names should start with a upper case letter: user should be User, courses - Courses.
Also note that the model name should not be in a plural form - better name courses as Course. Also better rename course field to name.
So, finally, here's the picture:
class User(models.Model):
name = models.CharField(max_length=30)
courses = models.ManyToManyField(Course)
class Course(models.Model):
name = models.CharField(max_length=100)
Hope that helps.