I extended my User
model with a new model just called UserExtended
:
# Django imports
from django.db import models
from django.contrib.auth.models import User
class UserExtended(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
crm_guid = models.UUIDField(unique=True)
security_q1 = models.CharField(max_length=255, blank=True, null=True)
security_a1 = models.CharField(max_length=255, blank=True, null=True)
security_q2 = models.CharField(max_length=255, blank=True, null=True)
security_a2 = models.CharField(max_length=255, blank=True, null=True)
attempts = models.SmallIntegerField(blank=False, null=False, default=0)
key = models.CharField(max_length=255, blank=True, null=True)
key_expires = models.DateTimeField(blank=True, null=True)
method = models.CharField(max_length=4, blank=True, null=True)
class Meta:
db_table = 'auth_user_extended'
I was hoping by just doing that some Django magic would take care of the rest and I wouldn't have to change my views.py
or serializers.py
. But when I send a request to the end-point I get:
[api] django.core.exceptions.ImproperlyConfigured: Field name `guid` is not valid for model `User`.
So it does apparently need to be specified. I've been looking at the documentation and similar SO questions to find an answer.
This is what I have for my views.py
:
# Django imports
from django.contrib.auth.models import User
# Third party imports
from rest_framework import generics
from rest_framework.permissions import IsAdminUser
# App imports
from users.serializers import UserSerializer
class UsersListCreateView(generics.ListCreateAPIView):
permission_classes = [IsAdminUser]
serializer_class = UserSerializer
def get_queryset(self):
queryset = User.objects.all()
email = self.request.query_params.get('email')
username = self.request.query_params.get('username')
if email:
queryset = queryset.filter(email=email)
if username:
queryset = queryset.filter(username=username)
return queryset
class UserRetrieveUpdateDeleteView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [IsAdminUser]
queryset = User.objects.all()
serializer_class = UserSerializer
For my serializers.py
I just have:
# Django imports
from django.contrib.auth.models import User
from users.models import UserExtended
from django.contrib.auth.hashers import make_password
# Third party imports
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'last_login', 'first_name',
'last_name', 'username', 'email', 'is_active', 'guid']
If I change model = User
to model = UserExtemded
, then I'll get an error like:
[api] django.core.exceptions.ImproperlyConfigured: Field name `last_login` is not valid for model `UserExtended`.
I'm thinking I need to do one of two things:
- Create a serializer class for both models and call them both from the
views.py
. I've toyed with this a little by trying to pass a list or tuple in ofserializer_class
(apparently singular for a reason). - Setup the relationship in the
serializers.py
. I'm looking into this now.
Suggestions for how to resolve this issue?
CodePudding user response:
You need a different serializer and viewset to operate on UserExtended
My suggestion would be keep old serializer as is and create UserExtendedSerializer
class UserExtendedSerializer(serializers.ModelSerializer):
user = UserSerializer(many=False, read_only=True)
class Meta:
model = UserExtended
fields = "__all__"
and viewset would be simply:
class UserExtendedViewSet(ModelViewSet):
serializer_class = UserExtendedSerializer
queryset = UserExtended.objects.all()
this should solve your issue