Reputation: 69
I already have a working auth.token registration using the django default User class, but i was asked to add a new field to the User, i investigate things as AbtractUser, AbstractBaseUser, etc. And i think the best solution will be the OneToOneField "method".
This is what i tried to do:
models.py:
class Usuario(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
es_tecnico = models.BooleanField(name = 'es_tecnico', default = False, blank = True)
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username',
'password')
class UsuarioSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = Usuario
fields = ('user',
'es_tecnico')
def create(self, validated_data):
"""
Overriding the default create method of the Model serializer.
:param validated_data: data containing all the details of student
:return: returns a successfully created student record
"""
user_data = validated_data.pop('user')
user = UserSerializer.create(UserSerializer(), validated_data=user_data)
usuario, created = Usuario.objects.update_or_create(user=user,
es_tecnico=validated_data.pop('es_tecnico'))
return usuario
views.py:
class UsuarioViewSet(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = UsuarioSerializer
queryset = Usuario.objects.all().filter(es_tecnico = False)
class TecnicoViewSet(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = UsuarioSerializer
queryset = Usuario.objects.all().filter(es_tecnico = True)
I want to make it work as simple as possible, this is what i get when i use the command "python3 manage.py makemigrations":
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/base.py", line 332, in execute
self.check()
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/base.py", line 364, in check
include_deployment_checks=include_deployment_checks,
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/management/base.py", line 351, in _run_checks
return checks.run_checks(**kwargs)
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/core/checks/registry.py", line 73, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/stalker/PycharmProjects/ingSoft/servidor/virenv/lib/python3.5/site-packages/django/contrib/auth/checks.py", line 29, in check_user_model
if not isinstance(cls.REQUIRED_FIELDS, (list, tuple)):
AttributeError: type object 'Usuario' has no attribute 'REQUIRED_FIELDS'
When i try solutions from others stackoverflow questions, i get this error:
AttributeError: type object 'Usuario' has no attribute 'USERNAME_FIELD'
if there is a simple way insted using OneToOneField i will apreciate it
This are the views where im having problem right now: views.py:
class Registrar(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = UsuarioSerializer
def create(self, request, *args, **kwargs):
# Creando un nuevo usuario
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
user = Usuario.objects.create_user(username, email, password)
user.save()
token = Token.objects.create(user=user)
return Response({'detail': 'El usuario fue creado con el token: ' + token.key})
class LoginView(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = LoginSerializer
def create(self, request):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["usuario"]
django_login(request, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"token": token.key}, status=200)
Upvotes: 1
Views: 2262
Reputation: 582
Here in your case you are just extending Django User
model, so you should not override AUTH_USER_MODEL
.
Delete this line of code from settings.py
file: AUTH_USER_MODEL = "pedidos.Usuario"
, and in your code if you want to use your User
model, this is the one you should use:
from django.contrib.auth.models import User
(as we said you are just extending Django User
model) or you can use the convenient function get_user_model()
get_user_model():
Instead of referring to User directly, you should reference the user model using django.contrib.auth.get_user_model(). This method will return the currently active user model – the custom user model if one is specified, or User otherwise.
If you want to get the attribute es_tecnico
of a User
you can use:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='Juan')
>>> juan_es_tecnico = u.usuario.es_tecnico
or using get_user_model()
:
>>> from django.contrib.auth import get_user_model
>>> my_user = get_user_model()
>>> u = my_user.objects.get(username='Juan')
>>> juan_es_tecnico = u.usuario.es_tecnico
Edit:
class Registrar(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = UsuarioSerializer
def create(self, request, *args, **kwargs):
# Creando un nuevo usuario
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
user = User.objects.create_user(username, email, password)
user.save()
token = Token.objects.create(user=user)
return Response({'detail': 'El usuario fue creado con el token: ' + token.key})
In Registrar
class use User
model instead of Usuario
.
I hope this will help.
Upvotes: 1