Extend the Django model

0

The problem I have not to extend Django's model is that I need to create more than one type of user in particular two Student and Teacher each with attributes in common but with others own of each one, someone could give me some idea or example.

Model.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from Perfiles import settings


class User(AbstractUser):
     is_estudiante = models.BooleanField(default=False)
     is_profesor = models.BooleanField(default=False)

    def get_estudiante_profile(self):
        estudiante_profile = None
        if hasattr(self, 'estudianteprofile'):
            estudiante_profile = self.estudianteprofile
        return estudiante_profile

    def get_profesor_profile(self):
         profesor_profile = None
    if hasattr(self, 'profesorprofile'):
        profesor_profile = self.profesorprofile
    return profesor_profile

class Meta:
    db_table = 'auth_user'


class EstudianteProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    anno = models.IntegerField(default=0)
    carrera = models.CharField(max_length=64)


class ProfesorProfile(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE)
   departamento = models.CharField(max_length=64)
   asignatura = models.CharField(max_length=64)


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
   def create_profile_for_new_user(sender, instance, **kwargs):
      if instance.is_estudiante:
         profile = EstudianteProfile(user=instance)
         profile.save()

     elif instance.is_profesor:
        profile = ProfesorProfile(user=instance)
        profile.save()
    
asked by Pedro Diaz Labiste 23.01.2018 в 01:02
source

2 answers

0

It can be done by adding an FK to the Student and User Teacher models or by inheritance 'class Teacher (User):' to create the teacher model in the same way with students. If you put your code, I can give you a more specific answer.

You've been doing it right you just have to create two models one for each type of user you want:

class Profesor(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    puesto = models.CharField(max_length=100, default='')
    edad = models.IntegerField(default=0)


class Estudiante(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    tutor = models.CharField(max_length=100, default='')
    fecha_nacimiento = models.DateField()
    phone_tutor = models.IntegerField(default=0)

The model.OneToOneField what it does is to relate the student or teacher model with User of django and with this you can access the attributes of Django User from student or teacher

views.py
try:
    profesor = Profesor.objects.get(user=request.user)
    print profesor.puesto
    prinf profesor.user.first_name
    #podrias haber accedido al first_name  directamente asi "request.user.firts_name" pero esta forma te aseguros de que el tipo de perfil sea de profesor
except Profesor.DoesNotExist:
     print "no existe un profesor con este usuario"

this same thing you can do with a student. I hope I have helped you, you are commenting on what comes up

What you can do is pass one more parameter per kwargs, for example type and we know that if one is a teacher and if two is a student

def create_profile(sender,**kwargs):
    if kwargs['created']:
        if kwargs['tipo'] == 1:
            user_profile =Profesor.objects.create(user=kwargs['instance'])
        else:
            user_profile =Estudiante.objects.create(user=kwargs['instance'])

This is a solution according to your code but it would be ideal if you create two forms and two classes in the view, if you register from the Student form in the student profile and if you are a teacher, that of a teacher, as separate processes let's go.

    
answered by 23.01.2018 / 13:48
source
0

One of the options that you could try is with an abstract class, which contains generic attributes and methods for all the models that inherit from it, and in the inheriting classes you can define own attributes

from django.contrib.auth.models import User
from django.db import models

class InfoBase(models.Model):
    name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    user = models.OneToOneField(User, blank=True, null=True)
    # puedes definir N campos que necesites en las clases que hereden

    class Meta:
        abstract = True


class EstudianteA(InfoBase):
    atributo1_estudianteA = models.CharField(max_length=100)
    atributo2_estudianteA = models.CharField(max_length=100)

class EstudianteB(InfoBase):
    atributo1_estudianteB = models.CharField(max_length=100)
    atributo2_estudianteB = models.CharField(max_length=100)


class Profesor(InfoBase):
    atributo1_profesor = models.CharField(max_length=100)
    atributo2_profesor = models.CharField(max_length=100)

It is important to note that the previous solution will not create a table in BD for the model InfoBase , it will create a table for each class that inherits from it which will contain the attributes defined in class infoBase and in the class that he inherits

In the same way if we need to differentiate what type of user it is, we can implement several approaches (your question is somewhat broad, but I will try to get to the point)

Use User Groups

You can create different user groups (django.contrib.auth.models.Group), to which add the user you just created, you can have a group called Profesores other called Estudiantes A and Estudiantes B

And in the view where you create the users assign them, according to each situation

from django.contrib.auth.models  import Group
#
#
def creacion_usuarios_profesores(request):
    # resto del code 
    grupo_profesores = Group.objects.get(name="Profesores")
    objeto_recien_creado.user.groups.add(grupo_profesores)
    # otras acciones
    objeto_recien_creado.user.save()

That way you can show, validate and exercise various actions, according to the, or the groups to which the user is assigned

Another Option

Another option that I have seen, but that I do not particularly like, could be to create in the class a tipo_usuario attribute related to a new Model called TipoUsuario where you store the different types of user that you consider, and based on that you can assign to then compare

Remember that this will depend on your business approach and the needs of the project

I hope it's your help

    
answered by 23.01.2018 в 22:06