djangodjango-signalsdjango-profiles

Django - multiple profiles


In my project I have two different types of users: teacher and student, each with their own profile data.

After searching for the best approach it seems the way to go forward is using multi-table inheritance:

class BaseProfile(models.Model):
    user = models.OneToOneField(User)
    profile = models.CharField (max_length=10, choices={'teacher', 'student'})
    # other common fields

class Teacher(BaseProfile):
    # teacher specific fields

class Student(BaseProfile):
    # student specific fields

And in settings.py: AUTH_PROFILE_MODULE = myapp.BaseProfile.

Now I want to implement the same functionalities as in django-profiles:

I have a good idea how to do the edit and display part when I have the correct value in the field profile of BaseProfile.

The problem:

Now I want the creation of the profile to be done automatically (and in the right db: Teacher or Student) directly when a user is created by using a signal. The field profile should contain the value "student" when the user registers through the site via the registration form. The value should be "teacher" when the admin creates a new user through the admin interface.

Anyone an idea how I can accomplish this? Probably I need to write a custom signal, something like the below, and send it from the User Model, but didn't found a working solution yet:

def create_user_profile(sender, instance, request, **kwargs):
    if request.user.is_staff:
        BaseProfile(user=instance, profile='teacher').save()
    else:
        BaseProfile(user=instance, profile='student').save()

Other and better approaches are of course also welcome!

Thanks!


Solution

  • In my opinion it isn't a good approach.

    I would recommend doing 1 unified profile which will contain an option: user_type = models.CharField(choices=[your_choices], max_length=4)

    Then in models you would create two forms - 1 for teacher and 1 for student.

    class ProfileFOrm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(BaseProfileForm, self).__init__(*args, **kwargs)
            for name in self.fields:
                self.fields[name].required = True
    
    class TeacherProfile(ProfileForm):
        class Meta:
            model = Profile
            fields = ('your_fields')
    
    
    class StudentProfile(ProfileForm):
        class Meta:
            model = Profile
            fields = ('school')
    

    That's just my idea for that :)


    Edited

    Profile edition:

    view.

    def profile(request):
    p = get_objects_or_404(ProfileModel, user=request.user)
    return TemplateResponse(request, 'template.html', {'profile': p})
    

    In models we need a function to check if user is a student or a teacher, so:

    class Profile(models.Model):
        ... your fields here...
        def get_student(self):
            return self.user_type == 1
    

    In templates:

    {% if profile.get_student%}
    
    >>>>get all data for students ex: <<<<
    {{profile.name}}
    
    {% endif %}
    
    
    {% if profile.get_teacher %}
    ....