samedi 29 novembre 2014

la base de données - Django, utilisateur en relation avec une autre table - Stack Overflow


So I got the tables you can see in the image below:


database.


What I would like to do is to create a relationship so that each user (of django auth_user) will be enrolled(or able to enrol) to exactly one "course" so that he will be able to see next events for his modules.


Do I have to create another table and place 2 foreign keys or this is a way to do it in 'php' and it's more simple with Django? I was suggested to create 'student' model inheriting from 'User' with extended behavior and one to many relationship on auth. I tried to do that but unfortunately had not results since I'm really new to Django & Python.




If every auth_user (or auth.User) will be or have the opportunity to be enrolled on a course I would create a 'user profile' model that has a 1-to-1 relationship with the django User model. You can store additional User data in this model, including what course they are enrolled on. See https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model for more details but here is an example:


class UserProfile(models.Model):
user = models.OneToOneField('auth.User')
course = models.ForeignKey('courseapp.Course', null=True)

You would probably need to create a signal that gets fired each time an auth.User object is saved, such that if it is the first time that User object has been saved, it automatically creates the UserProfile:


from django.contrib.auth.models import User
from django.db.models.signals import post_save
from yourusersapp.models import UserProfile

def create_user_profile(sender, instance, created, **kwargs):
# Automatically creates a UserProfile on User creation.
if created:
UserProfile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

When you query a User object, you can then reference the User object's profile like:


user_object.userprofile

You could then create a Course object and link the user_object indirectly via its UserProfile to that Course:


course = Course.objects.create(name='course_name', next_field='whatever')
user_profile = user_object.userprofile
userprofile.course = course
userprofile.save()

Now you have a user object with a UserProfile that is linked to only 1 course. Many users can be on the same course, but a user can only be on 1 course. You can also reference all users on a particular course like:


course = Course.objects.get(name='course_name')
course_users = course.userprofile_set.all()

HTH




I think that you can go about this one of two ways.



  1. Extend the User model. 'Student' would probably be a good name for your new model. It would have a OneToOne relationship with 'User', and a ForeignKey relationship with 'Course'. It can store any other information that is applicable to students only. Documentation for how to do that can be found here https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#extending-the-existing-user-model


  2. Create a custom User model that has a ForeignKey relationship with Course. This approach is a bit more complicated, but yields a slightly cleaner end result. Documentation for that is here. https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#substituting-a-custom-user-model



Sorry if it seems like I'm just sending you to the Django docs, but both of those sections are well written and should explain things pretty clearly. If you'd like to post another question with example code we can try and see why your original attempt at extending the User model didn't work. By the way, your "Student" model shouldn't have to inherit from the User model in order to extend it.



So I got the tables you can see in the image below:


database.


What I would like to do is to create a relationship so that each user (of django auth_user) will be enrolled(or able to enrol) to exactly one "course" so that he will be able to see next events for his modules.


Do I have to create another table and place 2 foreign keys or this is a way to do it in 'php' and it's more simple with Django? I was suggested to create 'student' model inheriting from 'User' with extended behavior and one to many relationship on auth. I tried to do that but unfortunately had not results since I'm really new to Django & Python.



If every auth_user (or auth.User) will be or have the opportunity to be enrolled on a course I would create a 'user profile' model that has a 1-to-1 relationship with the django User model. You can store additional User data in this model, including what course they are enrolled on. See https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model for more details but here is an example:


class UserProfile(models.Model):
user = models.OneToOneField('auth.User')
course = models.ForeignKey('courseapp.Course', null=True)

You would probably need to create a signal that gets fired each time an auth.User object is saved, such that if it is the first time that User object has been saved, it automatically creates the UserProfile:


from django.contrib.auth.models import User
from django.db.models.signals import post_save
from yourusersapp.models import UserProfile

def create_user_profile(sender, instance, created, **kwargs):
# Automatically creates a UserProfile on User creation.
if created:
UserProfile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

When you query a User object, you can then reference the User object's profile like:


user_object.userprofile

You could then create a Course object and link the user_object indirectly via its UserProfile to that Course:


course = Course.objects.create(name='course_name', next_field='whatever')
user_profile = user_object.userprofile
userprofile.course = course
userprofile.save()

Now you have a user object with a UserProfile that is linked to only 1 course. Many users can be on the same course, but a user can only be on 1 course. You can also reference all users on a particular course like:


course = Course.objects.get(name='course_name')
course_users = course.userprofile_set.all()

HTH



I think that you can go about this one of two ways.



  1. Extend the User model. 'Student' would probably be a good name for your new model. It would have a OneToOne relationship with 'User', and a ForeignKey relationship with 'Course'. It can store any other information that is applicable to students only. Documentation for how to do that can be found here https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#extending-the-existing-user-model


  2. Create a custom User model that has a ForeignKey relationship with Course. This approach is a bit more complicated, but yields a slightly cleaner end result. Documentation for that is here. https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#substituting-a-custom-user-model



Sorry if it seems like I'm just sending you to the Django docs, but both of those sections are well written and should explain things pretty clearly. If you'd like to post another question with example code we can try and see why your original attempt at extending the User model didn't work. By the way, your "Student" model shouldn't have to inherit from the User model in order to extend it.


0 commentaires:

Enregistrer un commentaire