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.
It would be nice if this use case was easier to find in the docs. As @jamod pointed out, in DRF 3, you can find it here:
When using Django Rest Framework you have to be careful. Any custom user model cannot utilize the built in token authentication. Until you can do that, I would suggest using a OneToOneField with user in your custom model. Your custom model will contain the extra fields you want to keep. One to One gives you access to the user from the custom user, and the custom user from the user.
If you're using django 1.5 or greater then use custom user model instead, this way user model will have it's own dedicated table and serializer will then pick up the fields correctly.
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:
You can do something like this to create both the custom user and django user:
Okay, a couple of things. You want to create a
OneToOneField
for your user model extension.Now, the power of Django Rest Framework, is you can build your serializer, to take data from both of these models when serializing.
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.I prefer to use the django signals module, which sends signals to the app when something happens, and among other things will let you call a function of your own before/after other functions. My answer is similar to Stuart's answer but keeps all of the code relevant to your new extension class in one place (if you want to delete the profile later or change its name you don't have to look anywhere else).
The following code lays out your extended class model, in this case a user profile, then creates an empty instance when a user model is created, then saves the instance with new information (that you must add yourself) by saving the parent user instance i.e. -
user.save()
models.py
If you don't have a ProfileSerializer: serializers.py
After you create your user and save your user, you'll have an empty user.profile to add information to. For example, after running
python manage.py shell
try: