Many to Many relationship Django Models with Extra Attributes - python

i'm a beginner in Django development (and MVC programming in general!)
considering the following example how could I translate these entities into models?
USER (id, name, surname)
ENGLISH_CERTIFICATION (id, code, name)
USER_CERTIFICATION (id, id_user, id_english_certification, date)
class User(models.Model):
name = models.CharField(max_length=64)
surname = models.CharField(max_length=64)
???
class EnglishCertification(models.Model):
code= models.CharField(max_length=2)
name = models.CharField(max_length=64)
???
Where i put the relationships and the field "date"?
Thank you!

If you want to create models that exactly represent the entities as you described, you could simply create an additional Model similar to:
class UserCertification(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
english_certification = models.ForeignKey('EnglishCertification', on_delete=models.CASCADE)
date = models.DateField()
Of course you will need to adapt the code above depending on your needs. For more information you can have a look at:
https://docs.djangoproject.com/en/2.1/topics/db/examples/many_to_one/
Hope this helps

Related

Django: Confusion with accessing database model's foreign key data

This is my first time working with Django and while working I have encountered with a confusion to create a particular statement in views that leads to my desired output. I have created a model 'Parents' which has data of a specific student (Foreign Key), and I am confused to access that student id for further process like working with Attendance, or Results of that specific student. Below are necessary codes and my trial to fetch data.
Models.py
class Students(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
gender = models.CharField(max_length=50)
address = models.TextField()
course_id = models.ForeignKey(Courses, on_delete=models.DO_NOTHING, default=1)
session_year_id = models.ForeignKey(SessionYearModel, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager()
def __str__(self):
return self.admin.first_name + " " + self.admin.last_name
class Parents(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
gender = models.CharField(max_length=50)
**student = models.ForeignKey(Students, on_delete=models.CASCADE)**
relation = models.CharField(max_length=255)
address = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager()
def __str__(self):
return self.admin.first_name + " " + self.admin.last_name
Here I have two models, Students model has all information regarding student and the other model is Parent model which has parent information with its specific student id.
Below is the views file code where I am trying to fetch student id of currently logged in parent,
def HOME(request):
stud_data = Parents.objects.filter(student__id = request.user.id)
print(stud_data)
return None
At the time of page reload, I am able to get an empty QuerySet[] as it is not able to find the id.
Kindly help me finding the solution to this problem, so that I can continue thinking about the development.
Thanks :)
As you mentioned here, you are looking for Student data for currently logged in Parent. Hence you can look for Student data directly from Parent object. Like this:
stud_object = request.user.parent.student
This relation works because Parent has a OneToOne relation with CustomUser (I assume Authentication's custom User model), hence you should get Parent object from request.user.parent (reverse relation for OneToOne). Also, student field is a ForeignKey of Parent model.
Addionally, I think the relation between Parent and Student should be ManyToMany, because a Student can have multiple parents and one parent can have multiple students (or children).
There are two possibilities:
The View code that you have attached should be returning stud_data not None, but I am assuming that you know this and this current state of the code is just for debugging purposes.
The request.user.id contains a value that doesn't belong to any student's ID in the database. As you are using filter, it's not going to complain about it and just return you an empty QuerySet. I'd suggest using the get() filter here which raises the DoesNotExist exception and would help in debugging as well.
def home(request):
stud_data = Parents.objects.get(student__id = request.user.id)
return stud_data
Hope it helps!
Best of luck with your new journey!

Do i need to update AUTH_USER_MODEL in my settings.py?

I am creating my own users, Restaurant and Customer. I have extended the AbstractUser class and then created a OneToOneField field for each user. I am wondering if I need to add the AUTH_USER_MODEL in my settings.py. And also wondering what that does exactly...
What I was planning on doing was adding to my settings.py:
AUTH_USER_MODEL = 'myapp.Customer','myapp.Restaurant'
Do I have the right idea here?
My models.py:
class User(AbstractUser):
is_restaurant = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Restaurant(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
restaurant_name = models.CharField(max_length=50)
def __str__(self):
return self.restaurant_name
class Customer(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.user.get_full_name()
No. AUTH_USER_MODEL isn't expecting a tuple, so this won't work.
In any case, Restaurant and Customer are not your user model; your subclassed User is. That's what you should be putting in that setting.
I would suggest create single user table instead of three different tables and add type as restaurant, customer, admin etc. And add only one table into settings file. this won't lead any further issues authentication etc. Having single user table is always robust. In your case having three tables seems not good to maintain.
========== UPDATE ===========
Create model for user named as CustomUser (or name which you feel better) and extends to User Model of Django using AbstractBaseUser,PermissionsMixin. like
class CustomUser(AbstractBaseUser): have all fields which user table has already. and add your desired table to bifurcate type of restaurant and
customer have type field with choices option.
For further help you can check section https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model

Dynamic generation ForeignKey fields on admin page django

I have models:
class CompanyInfo(models.Model):
name = models.CharField('Имя компании',max_length=250)
class Staff(models.Model):
company_name = models.ForeignKey(CompanyInfo)
date = models.DateField( )
name = models.CharField( max_length=30, )
class Relation(models.Model):
company_name = models.ForeignKey(CompanyInfo)
who = models.ForeignKey(Staff, related_name="who")
with_whom = models.ForeignKey(Staff, related_name="with_whom")
info = models.CharField( max_length=30, )
How I can create dynamic generation fields for WHO and WITH_WHOM form element on the admin-page? I chose COMPANY_NAME, and fields WHO and WITH_WHOM that show only people from that company.
Can you please elaborate in a bit more detail on what you mean by dynamic generation fields? Otherwise, I'm afraid it's a bit difficult to help you because it's not really clear what your problem is.
Besides that, let me tell you that your model design is rather odd, especially your Relation model. If you want to establish a many-to-one relationship between two instances of the same model (I think that's what you are trying to accomplish here), then you should write it like that and get rid of your Relation model:
class Staff(models.Model):
with_whom = models.ForeignKey('self')

Querying over many to many field

I have following models setup in my Django application
class School(models.Model):
name = models.TextField()
class Courses(models.Model):
name = models.TextField()
schools = ManyToManyField(School)
Now, I want to find out all schools which offer a particular course. For example, find all schools which offer biology and chemistry. What query can I use?
thanks
See lookup that span relationships in the manual:
class Courses(models.Model):
name = models.TextField()
schools = ManyToManyField(School, related_name='courses_set')
School.objects.filter(courses_set__name__in=('biology', 'chemistry'))

Django import problem with models.py and multiple ManyToManyFields()

I am working on creating a simple contest submission system using django. This is my first real django project. Basically each user can view a list of problems, submit a file, and view a results page.
Each problem can be associated with multiple contests, and different contests can use the same problem. Because of this, both problem and contest have a manyToManyField with each other. This is what is causing my problem.
Here is the initial models.py implementation I am going with:
startfile
from django.db import models
class User(models.Model):
username = models.CharField(max_length=50)
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
class Problem(models.Model):
name = models.CharField(max_length=50)
filename = models.CharField(max_length=300)
contests = models.ManyToManyField(Contest)
class Contest(models.Model):
name = models.CharField(max_length=50)
problems = models.ManyToManyField(Problem)
date = models.DateField()
class Submission(models.Model):
user = models.ForeignKey(User)
problem = models.ForeignKey(Problem)
filename = models.CharField(max_length=300)
endfile
Is there a simple way to fix this? Or should I rethink my entire layout? I tried breaking each class into its own django app but I don't think thats how I should do it. The error I get is that Contest can not be found (because it exists lower in the file).
All advice is appreciated!
You don't need a ManyToManyField in both Contest and Problem. Many-to-many fields are already bidirectional. Just put it on one - doesn't matter which.
Djano will automatically create the reverse relation for you, so you only need to create it one end, eg.
class Problem(models.Model):
name = models.CharField(max_length=50)
filename = models.CharField(max_length=300)
contests = models.ManyToManyField(Contest, related_name='problems')
related_name gives you the possibility to assign a name to the reverse relation. Without defining the relation on the Contest model, you can then access eg. a_contest.problems.all()!

Categories

Resources