Can not assign "'Maria'": "Student.name_mae" must be a "Student" instance. When I try to access a field from the student subclass

5

I have a system with multiple users, I decided to make inheritance from the standard Django User, I have two users: student and teacher, which has several characteristics in common, so I created a User base class and subclasses Student and Teacher .

account / models.py

class User(AbstractBaseUser, PermissionMixin):
    username = models.CharField('Usuário', max_length=30, unique=True,
        validators=[validators.RegexValidator(re.compile('^[\w.@+-]+$'),
            'O nome de usuário só pode conter letras, digitos ou os '
            'seguintes caracteres: @/./+/-/_', 'invalid')]
    )

    nome = models.CharField('Nome', max_length=100)
    email = models.EmailField('E-mail', unique=True) # blank=True?
    instituicao = models.CharField('Instituição', max_length=200)
    SEXO_CHOICE = ((0, 'Masculino'), (1, 'Feminino'))
    sexo = models.IntegerField('Sexo', choices=SEXO_CHOICE, default=0)
    imagem_perfil = models.ImageField('Imagem do perfil', upload_to='media/img/%Y/%m/%d', blank=True)
    is_active = models.BooleanField('Está ativo?', blank=True, default=True)
    is_staff = models.BooleanField('É administrador?', blank=True, default=False)
    date_joined = models.DateTimeField('Data de Entrada', auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return self.nome

    def get_short_name(self):
        return str(self)

    def get_full_name(self):
        return self.nome

    class Meta:
        verbose_name = 'Usuário'
        verbose_name_plural = 'Usuários'

student / models.py

class Aluno(User):
    nome_mae = models.CharField('Nome da Mãe ', max_length=100)

    class Meta:
        verbose_name = 'Aluno'
        verbose_name_plural = 'Alunos'

teacher / models.py

class Professor(User):
    endereco = models.CharField('Endereço', max_lenght=100)

    class Meta:
        verbose_name = 'Professor'
        verbose_name_plural = 'Professores'

views.py

def dashboard_aluno(request):
    user = User.objects.all()
    aluno = Aluno.objects.all()
    professor = Professor.objects.all()
    print(user)
    print(aluno)# o erro acontece nessa linha
    print(professor)
    turma_aluno = Turma.objects.filter(alunos__id__contains=request.user.id)
    disciplina_aluno = Disciplina.objects.filter(turmas__id__contains=turma_aluno[0].id)
    template_name = 'dashboard_aluno.html'
    context = {'turma_aluno': turma_aluno, 'disciplina_aluno': disciplina_aluno}
    return render(request, template_name, context)

I can log in with both types of users, but when I try to access information that is only one of the types of users, for example the student_name I get the error:

Traceback:

File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/rede_social/conta/views.py" in dashboard_aluno
  18.     print(aluno)
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/query.py" in __repr__
  116.         data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/query.py" in __iter__
  141.         self._fetch_all()
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/query.py" in _fetch_all
  966.             self._result_cache = list(self.iterator())
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/query.py" in iterator
  275.                     obj = model(*row_data)
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/base.py" in __init__
  382.                 setattr(self, field.attname, val)
File "/home/andre/andre/ifce/iniciacaocientifica/rede_social/projeto/venv/lib/python3.4/site-packages/django/db/models/fields/related.py" in __set__
  454.                     self.related.opts.object_name,

Exception Type: ValueError at /conta/dashboard_aluno/
Exception Value: Cannot assign "'Maria'": "Aluno.nome_mae" must be a "Aluno" instance.

I'm new to Django, so any advice or tip I'll gladly accept. I'm using version 1.7.7 and python 3.4

Ps: Is this the best way to have multiple users?

    
asked by anonymous 11.06.2015 / 19:56

1 answer

1

After a week of searching, find out that the error was in creating the Professor and Aluno subclasses in different apps. I solved the problem by creating the subclasses in the same file as the base class User :

account / models.py

class User(AbstractBaseUser, PermissionMixin):
    username = models.CharField('Usuário', max_length=30, unique=True,
        validators=[validators.RegexValidator(re.compile('^[\w.@+-]+$'),
            'O nome de usuário só pode conter letras, digitos ou os '
            'seguintes caracteres: @/./+/-/_', 'invalid')]
    )

    nome = models.CharField('Nome', max_length=100)
    email = models.EmailField('E-mail', unique=True) # blank=True?
    instituicao = models.CharField('Instituição', max_length=200)
    SEXO_CHOICE = ((0, 'Masculino'), (1, 'Feminino'))
    sexo = models.IntegerField('Sexo', choices=SEXO_CHOICE, default=0)
    imagem_perfil = models.ImageField('Imagem do perfil', upload_to='media/img/%Y/%m/%d', blank=True)
    is_active = models.BooleanField('Está ativo?', blank=True, default=True)
    is_staff = models.BooleanField('É administrador?', blank=True, default=False)
    date_joined = models.DateTimeField('Data de Entrada', auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return self.nome

    def get_short_name(self):
        return str(self)

    def get_full_name(self):
        return self.nome

class Meta:
    verbose_name = 'Usuário'
    verbose_name_plural = 'Usuários'

class Aluno(User):
    nome_mae = models.CharField('Nome da Mãe ', max_length=100)

    class Meta:
        verbose_name = 'Aluno'
        verbose_name_plural = 'Alunos'

class Professor(User):
    endereco = models.CharField('Endereço', max_lenght=100)

    class Meta:
        verbose_name = 'Professor'
        verbose_name_plural = 'Professores'
    
19.06.2015 / 18:58