Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework Creating custom user

Tags:

I'm new in Django realm but see there is a lot of "magic" there. I'm using Django REST Framework and creating app that will allow free user registration. My user needs some additional fields that are not available in Django user. So I googled for extending User. There is an idea that this should be done by creating something like this

class MyUser(models.Model):     user = models.ForeignKey(User, unique=True)     city = models.CharField(max_length=50, blank=True, default='') 

This is fine but I have this serializer

class UserSerializer(serializers.ModelSerializer):     class Meta:         model = MyUser         fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'city') 

So, the problem is that this serializer does some "magic" here. It tries to figure out what field should model have ... I want to have user with fields listed here, and these are fields are in User and 'city' is new custom field. Serializer doesn't get that it should look inside User model.

What am I missing here? How to tell this serializer that I want some fields inside User? I need to be able to crete user too.

like image 843
Bojan Radojevic Avatar asked Nov 04 '13 16:11

Bojan Radojevic


People also ask

Should you create custom user model in Django?

It's highly recommended to set up a custom User model when starting a new Django project. Without it, you will need to create another model (like UserProfile ) and link it to the Django User model with a OneToOneField if you want to add new fields to the User model.


2 Answers

So apparently I don't have enough reputation to post a comment under an answer. But to elaborate on what Kevin Stone described, if you model is something like the following:

class AppUser(models.Model):     user = models.OneToOneField(User)     ban_status = models.BooleanField(default=False) 

You can do something like this to create both the custom user and django user:

class AppUserSerializer(serializers.ModelSerializer):     username = serializers.CharField(source='user.username')     email = serializers.CharField(source='user.email')     password = serializers.CharField(source='user.password')     ban_status = serializers.Field(source='ban_status')      class Meta:         model = AppUser         fields = ('id', 'username', 'email', 'password', 'ban_status')      def restore_object(self, attrs, instance=None):         """         Given a dictionary of deserialized field values, either update         an existing model instance, or create a new model instance.         """         if instance is not None:             instance.user.email = attrs.get('user.email', instance.user.email)             instance.ban_status = attrs.get('ban_status', instance.ban_status)             instance.user.password = attrs.get('user.password', instance.user.password)             return instance          user = User.objects.create_user(username=attrs.get('user.username'), email= attrs.get('user.email'), password=attrs.get('user.password'))         return AppUser(user=user) 
like image 163
Anton K Avatar answered Oct 08 '22 08:10

Anton K


Okay, a couple of things. You want to create a OneToOneField for your user model extension.

class MyUser(models.Model):     user = models.OneToOneField(User)     city = models.CharField(max_length=50, blank=True, default='') 

Now, the power of Django Rest Framework, is you can build your serializer, to take data from both of these models when serializing.

class UserSerializer(serializers.ModelSerializer):     city = serializers.CharField(source='myuser.city')     class Meta:         model = User         fields = ('id', 'username', 'password', 'first_name', 'last_name', 'email', 'city') 

Finally, where you're creating the user, since you're using custom fields, you need to implement your own restore_object() that builds both models from the input data.

Also, creating Users in Django is a bit different, you need to call create_user() and supply a password that is hashed, so its not as simple as storing fields from a serializer.

like image 26
Kevin Stone Avatar answered Oct 08 '22 10:10

Kevin Stone