My Django application provides readonly api access to the users of the site. I created a user profile model and use it in the serializer of the user model:
Model:
# + standard User Model
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
display_name = models.CharField(max_length=20, blank=True)
Serializer:
class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserProfile
fields = ('display_name',)
class UserSerializer(serializers.HyperlinkedModelSerializer):
userprofile_set = UserProfileSerializer(many=False, label='userprofile')
class Meta:
model = User
fields = ('id', 'username', 'userprofile_set')
This works but the field userprofile_set looks ugly. Is it possible to change the field name?
To complement your answer, you can also make use of relationships' related names:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True, related_name='profiles')
display_name = models.CharField(max_length=20, blank=True)
that way you can also use this in your code:
user = User.objects.last() #some user
user.profiles.all() #UserProfiles related to this user, in a queryset
user.profiles.last() #the last UserProfile instance related to this user.
May I recommend that you turn that ForeignKey into a OneToOneField? that way an user can have one and just one user profile, and you don't need to establish uniqueness:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
display_name = models.CharField(max_length=20, blank=True)
Oh, I can name the variable userprofile_set as I like. First I tested the name userprofile which conflicted. If I name the field profile it works. :)
class UserSerializer(serializers.HyperlinkedModelSerializer):
profile = UserProfileSerializer(many=False, label='userprofile')
class Meta:
model = User
fields = ('id', 'username', 'profile')
Related
I am trying to make a user Signup system along with his profile.
my models.py:
class myCustomeUser(AbstractUser):
username = models.CharField(max_length=50, unique="True", blank=False)
password = models.CharField(max_length=200, blank=False)
USERNAME_FIELD = 'username'
class Profile(models.Model):
user = models.OneToOneField(myCustomeUser, null=True, on_delete=models.CASCADE)
bio = models.TextField()
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/profile/")
my forms.py:
class SignUpForm(ModelForm):
class Meta:
model = Profile
fields = '__all__'
my views.py:
class index(generic.CreateView):
form_class = SignUpForm
template_name = 'index.html'
Now here my problem is, the form gives me an option to choose any user (with dropdown) to create a profile.... but I want to create a user also on that page (not pick an option from dropdown). How can I try for that?
Your need to connect your user creation form with Django post_Save signals.
I will point out a tutorial that can assist you
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
Your signup form should use myCustomeUser
So that you create a user first
Then.with the help of "signals" you can create profiles automatically every time a user is created
Hello I am very new to Django Rest Framework and I am having a hard time with the serializer. I extended the User Model using Abstract User. I inserted two new fields which are is_student and is_teacher then I set both of the values to false as default. I then put them in there own model then just applied a one-to-one relation for each of them to the user model. My problem is with the serializer. How do I make a serializer out of this. I want the student and teacher have relation with the user model as well as having the ability to do http actions such as get, post, put, etc.
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
# Create your models here.
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
class Course(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
price = models.FloatField()
def __str__(self):
return self.name
class Student(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True)
age = models.IntegerField()
address = models.CharField(max_length=200)
def __str__(self):
return self.user.username
class Teacher(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True)
description = models.TextField()
course_teaching = models.ForeignKey(Course, on_delete=models.CASCADE)
students = models.ManyToManyField(Student)
def __str__(self):
return self.user.username
Check out an example of this type of serializer here: https://github.com/imagineai/create-django-app/blob/master/todoapp/serializers.py
i am newbie in Django and DRF.
I created object of User class(which is in models.py) and i want with THAT user log in to django. In a nutshell, create django user with model User class. How can i implement it?
models.py
class User(models.Model):
username = models.CharField(max_length=20, unique=True) #login field in Angular
password = models.CharField(max_length=30)
first_name = models.CharField(max_length=30) # name field in Angular
last_name = models.CharField(max_length=30)
email = models.EmailField(
unique=True,
max_length=254,
)
views.py
class UserCreateAPIView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
SerializerClass
class UserSerializer(serializers.ModelSerializer):
username = serializers.CharField(write_only=True)
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = '__all__'
You can use simple django auth, very easily explained in the article below
https://simpleisbetterthancomplex.com/tutorial/2016/06/27/how-to-use-djangos-built-in-login-system.html
Also, for having a better authentication system, I would suggest you to look for simple JWT tokens:
https://simpleisbetterthancomplex.com/tutorial/2018/12/19/how-to-use-jwt-authentication-with-django-rest-framework.html
I cant find a way to auto-populate the field owner of my model.I am using the DRF .If i use ForeignKey the user can choose the owner from a drop down box , but there is no point in that.PLZ HELP i cant make it work.The views.py is not include cause i think there is nothing to do with it.
models.py
class Note(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
cr_date = models.DateTimeField(auto_now_add=True)
owner = models.CharField(max_length=100)
# also tried:
# owner = models.ForeignKey(User, related_name='entries')
class Meta:
ordering = ('-cr_date',)
def __unicode__(self):
return self.title
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', "username", 'first_name', 'last_name', )
class NoteSerializer(serializers.ModelSerializer):
owner = request.user.id <--- wrong , but is what a need.
# also tried :
# owner = UserSerializer(required=True)
class Meta:
model = Note
fields = ('title', 'body' )
Django Rest Framework provides a pre_save() method (in generic views & mixins) which you can override.
class NoteSerializer(serializers.ModelSerializer):
owner = serializers.Field(source='owner.username') # Make sure owner is associated with the User model in your models.py
Then something like this in your view class:
def pre_save(self, obj):
obj.owner = self.request.user
REFERENCES
http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions#associating-snippets-with-users
https://github.com/tomchristie/django-rest-framework/issues/409#issuecomment-10428031
I'm using django-allauth and I want to be able to add new field to my User model.
What's the best way to do this as of you ?
I use userena. But I am sure that it will look almost the same ;)
class UserProfile(UserenaBaseProfile):
user = models.OneToOneField(User, unique=True)
city = models.CharField(max_length=32, blank=True, null=True)
in settings.py:
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
See the docs Storing additional information about users, Make a model with OneToOneField relation to User.
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
accepted_eula = models.BooleanField()
favorite_animal = models.CharField(max_length=20, default="Dragons.")