5
I have a system with multiple users, I decided to make inheritance of Django’s default user, I have two users: student and teacher, which has several characteristics in common, so I created a base class User and the subclasses Pupil and Professor.
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'
professor/models.py
class Professor(User):
endereco = models.CharField('Endereço', max_lenght=100)
class Meta:
verbose_name = 'Professor'
verbose_name_plural = 'Professores'
py views.
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 field name_mae user’s Pupil i get the bug:
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’d be happy to take. I am using version 1.7.7 and python 3.4
Ps.: This is the best way to have multiple users?
You just put the template, put also the part of the code that is generating the error.
– Paulo
That one
UserManager
is something of Django’s own or did you create it? What does it do? It has how to put the stack trace error whole in question, instead of only the message? Apparently you created the query set normally (usingobjects.all()
) but at the time of executing it gave some problem. My only guess is that it may be a problem in theManager
. I have no experience with recent versions of Django (after 1.5), so I can’t tell you whether or not it’s right to make subclasses ofUser
this way. Why not instead create a separate template withOneToOneField
forUser
?– mgibsonbr
@mgibsonbr the 'Usermanaget' is Django’s own, basically this says which Manager(create user and superuser) I will use, in this case I use Django’s own. I thought about creating with Onetoonefield but I thought about DRY, since my project will be much more complex.
– 4ndr3
I don’t see any additional complexity - a "subclass" is simply an extra table whose primary key is also a foreign key to another table... Even call
User.objects.all()
returns all users - including students and teachers - but you only have access to class fieldsUser
. That is, the difficulty to use is more or less the same. In time: I’m not saying that doing subclass is bad, I’m just saying that me I have no experience with recent versions of Django to give an opinion on this practice.– mgibsonbr