How to use django ORM for dynamic binding relation? - django

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.

Related

what is related_name and related_query_name in 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/

How to call a a field of one model A into another model B so that b can work as a view

I have created a model called Department, Course. Models are as follow
This is the model for departments and course
class Departments(models.Model):
Department_Id = models.IntegerField(primary_key=True)
Department_Name = models.CharField(max_length=200)
Department_Code = models.CharField(max_length=200)
class Course(models.Model):
Course_Id = models.IntegerField(primary_key=True)
Department_Id = models.ForeignKey(Departments, on_delete=models.CASCADE)
Course_Name = models.CharField(max_length=200)
Course_Code = models.CharField(max_length=200)
I want to create a model called view which can be later on called for search. I want a view model in a such a way that it consit of the data in concat form i.e. name= Department_name+ Course_Name
class View (models.model):
view_id= models.IntegerField(primary_key=True)
Name= Department_name(I want this from Departments table)
+ Course_Name(I want this from Course table)
I try using one to one relation . I would really appricate the help
It's not clear why you'd want to do that. It's never a good idea to duplicate data from one model into another one, as it can lead to inconsistencies.
You can add a ForeignKey in View to your Course model and then when you do f"{view.course.name} {view.course.department.name}" you already have your string:
class View(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def name(self):
return f"{self.course.name} {self.course.department.name}"
Notes:
Don't call your foreign key Department_id because it's not referring to the id but to the object itself in the Django ORM: department = models.ForeignKey(Department, on_delete=models.CASCADE). As you can see, this makes reading the code much simpler: self.course.Department_id is a Department object not an integer, so self.course.department makes more sense.
Don't prefix your field names with the class, it just makes the code so much less readable: Do you prefer department.name or department.Department_name?
The View model is still a mystery to me, as you can search without it. You can search for example for courses with a matching department name like this:
Course.objects.filter(department__name__icontains="maths")
which will return all courses with "maths" in their department name.
Remove all the ids from your models, they are created automatically by Django anyway (and called id). Again, department.id is much easier to read than department.Department_id. Also in your code, you have to generate the ids yourself since you don't set them to auto-populate.

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.

In Django, how can I perform the following many-to-many query (using a through table)?

In my model I have a table for users (who are students or instructors - I have a UserProfile table that is connected to auth.User), a table for courses, and a table called enrollment, which records which students are enrolled in which courses. My models.py is as follows:
class Course(models.Model):
name = models.CharField(max_length=40)
instructor = models.ForeignKey(UserProfile, related_name="Instructor")
students = models.ManyToManyField(UserProfile, through='Enrollment')
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
role = models.CharField(max_length=4, choices=ROLE_CHOICES) # 'stud' or 'inst'
class Enrollment(models.Model):
course = models.ForeignKey(Course)
student = models.ForeignKey(UserProfile)
For a given User, I would like to find all the courses s/he is enrolled in. How can I do this?
Also, where can I find a thorough explanation of how to do queries in Django, preferably with lots of examples that slowly increase in complexity?
If you have a UserProfile instance user_profile, then try:
courses = Course.objects.filter(students=user_profile)
if you have a User instance user, then you can use double underscore notation.
courses = Course.objects.filter(students__user=user)
For an explanation, I would start with the django docs for Making queries. Other people might have some other suggestions.
As an aside: in this case, unless you are using a legacy db, you don't really need to explicitly define the joining table Enrollment, as you haven't defined any extra fields.
If instead of a User instance you have the username field from the User instance you could do the following:
courses = Course.objects.filter(students__user__username='thespecificusername')
The scenario you're constructing is very similar to the one discussed here: https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships