How to do user registration in Django REST framework api - python

I have searched the whole web and cant find any satisfying answer
I have changed my user model by adding some custom fields
So now i got
'username',
'password',
'email',
'first_name',
'last_name',
'phonenumber',
'address'
instead of
'username',
'password',
'email',
'first_name',
'last_name', --- (these are default)---
This is my models.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class userinformation(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phonenumber = models.CharField(max_length=100)
address = models.CharField(max_length=200)
class Meta:
verbose_name_plural = "User Information"
def __str__(self):
return str(self.user)+' - '+self.phonenumber+' - '+self.address
Im trying to make a Django REST framework api on which i can post
'username',
'password',
'email',
'first_name',
'last_name',
'phonenumber',
'address'
And register user with these details
what should i add in my veiws.py and serializers.py

Adding these other fields comes from manipulating the serializer. You could do something like this to expose those fields if you add field related_name='user_information' to your model definition:
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_information')
Then you create a serializer like:
class UserSerializer(serializers.HyperlinkedModelSerializer):
phonenumber = serializers.CharField(source='user_information.phonenumber')
address = serializers.CharField(source='user_information.address')
class Meta:
model = User
fields = ('username', 'password', 'email', 'first_name', 'last_name',
'phonenumber', 'address')
and instantiate that serializer in your view:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
[...]

Related

How to use Djoser with multiple extended users?

Hello I am new to django django rest framework and djoser I was just wondering. How do I use djoser with multiple extended users. Below is my model, serializers and views. I can't really find anything in the internet. And the Djoser documentation doesn't have anything on multiple users. Should I just use the build in token authentication of Django Rest Framework?
Model:
I am trying to inherit user with the student model and teacher model (as seen below). I want djoser to use these two model to create the users.
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
# Create your models here.
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='student')
age = models.IntegerField()
address = models.CharField(max_length=200)
def __str__(self):
return self.user.username
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='teacher')
description = models.TextField()
def __str__(self):
return self.user.username
class Course(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
price = models.FloatField(default=25.00)
def __str__(self):
return self.name
Serializer:
My serializer is not finished yet I still have to override the create and update methods.
from rest_framework import serializers
from api.models import *
from django.contrib.auth.models import User
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ('age', 'address')
class StudentUserSerializer(serializers.ModelSerializer):
student = StudentSerializer()
class Meta:
model = User
fields = ('id', 'username', 'email', 'password', 'first_name', 'last_name', 'student')
extra_kwargs = {'password': {'write_only': True, 'required': True}}
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('description', )
class TeacherUserSerializer(serializers.ModelSerializer):
teacher = TeacherSerializer()
class Meta:
model = User
fields = ('id', 'username', 'email', 'password', 'first_name', 'last_name', 'teacher')
extra_kwargs = {'password': {'write_only': True, 'required': True}}
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = '__all__'
Views:
As well as my views I still have to setup permissions for the views.
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from api.serializers import *
from api.models import *
from django.contrib.auth.models import User
# Create your views here.
class CourseView(ModelViewSet):
serializer_class = CourseSerializer
queryset = Course.objects.all()
class StudentView(ModelViewSet):
serializer_class = StudentUserSerializer
queryset = User.objects.all()
class TeacherView(ModelViewSet):
serializer_class = TeacherUserSerializer
queryset = User.objects.all()
Override the ModelViewset's perform_create() methods of TeacherView and StudentView to also create a user object.

Creating user without username (or with auto-generated username)

I want to create a registration page that doesn't ask for an username, since i'm not planning on using it (i only need email and password).
However, i'm not sure how to tell django that username is not mandatory.
I'm having trouble registering users because they all get the same username (blank).
My user model:
class User(AbstractUser):
departments = models.ManyToManyField(Department)
def __str__(self):
return f'{self.first_name} {self.last_name}'
My form for registering:
class UserCreateForm(UserCreationForm):
class Meta():
fields = ('first_name', 'last_name', 'email', 'departments', 'password1', 'password2')
model = get_user_model()
The view:
class SignUpView(CreateView):
form_class = UserCreateForm
success_url = reverse_lazy('loginPage')
template_name = 'accounts/signup.html'
What should i change in order to tell django to ignore the username field for the User model?
Is a random auto-generated username a good idea to avoid this problem? If yes, how do i code it?
#Shahzeb Qureshi, i tried this:
from django.utils.translation import gettext_lazy
class UserCreateForm(UserCreationForm):
class Meta():
fields = ('first_name', 'last_name', 'username', 'departments', 'password1', 'password2')
model = get_user_model()
labels = {
'username':gettext_lazy('E-mail'),
}
A simple solution would be that you enter the email address in your username field instead of leaving it blank.
Just generate the username from email use the code is given below
email = 'punnapavankumar9#gmail.com'
username = email.split('#')[0]

What is the significance of fields in Meta Class of UserCreationForm in Django?

I am a Django noob and I have a question I know the people of this beautiful community can help me answer.
In my Django project I have created a custom user (using AbstractUser) having a custom field 'number'.
The custom user model is named AdminUser.
#models.py
class AdminUser(AbstractUser):
number = PhoneNumberField(blank=False, unique=True, editable=True)
is_staff = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
REQUIRED_FIELDS = ['number']
objects = AdminUserManager()
def __str__(self):
return self.username
I have assigned a custom UserAdmin for this class
#admin.py
class CustomUserAdmin(UserAdmin):
form = AdminUserChangeForm
add_form = AdminUserCreationForm
model = AdminUser
list_display = ['username', 'first_name', 'last_name', 'number']
list_filter = ['is_superuser', 'first_name']
"""Fields when editing users"""
fieldsets = UserAdmin.fieldsets + (
('Primary Contact', {'fields': ('number',)}),
)
"""Fields when adding new user"""
add_fieldsets = UserAdmin.add_fieldsets + (
('New User Credentials', {'fields': ('number', 'is_staff', 'is_superuser', 'first_name', 'last_name', 'email')}),
)
And forms like so
#forms.py
class AdminUserCreationForm(UserCreationForm):
class Meta(UserChangeForm.Meta):
model = AdminUser
#how does 'fields' below affect the form structure??
fields = ('username', 'email', 'number')
class AdminUserChangeForm(UserChangeForm):
class Meta:
model = AdminUser
fields = ('username', 'email', 'number')
My question is how do the 'fields' tuple in Meta class in forms.py affect the structure of the creation and change forms?
When I remove or add an element to the fields tuple there is no difference in these forms in Django admin.
It is the fieldsets and add_fieldsets in CustomUserAdmin that effects the form structure.
So what is the use of fields in the Meta class of forms.py?
Are they just for informatic use?
I suspect that if your CustomerAdmin was not inherited from UserAdmin, it would work as expected. The ModelAdmin fields you use will override the fields specified on the form.
If you use ModelForms outside of the admin, it will also work as you expect, but the admin is kind of an old kludgy thing and might not always work the way you think.
In general, the fields specifies which fields from the model to show, as you suggest, and it will work in most cases (just not in this one).

How to not accept one email address for multiple registration accounts in django?

I made a registration page in django but the problem is that it should not accept one email address for multiple accounts. How to resolve this issue? If you need code then let me know.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
forms.py
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email','password1','password2']
No need of entering email in forms , User model already contains a email column
your registration form should look like this
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
and you can simply use this line in models.py to make email Unique
User._meta.get_field('email')._unique = True

Passwords won't get hashed and password input not working

I am currently trying to improve my knowledge in coding only by using class-based views. I am currently using Django 2.0.7 and I got a bit stuck. I was trying to extend the User model in order to create accounts. This was easily done. But I can't make the passwords to get hashed. Also, when I try to type, it will not be hidden even when using PasswordInput widget. Any advice ?
#models.py
class Client(User):
name = models.CharField(max_length=30)
surname = models.CharField(max_length=50)
phone = models.CharField(max_length=15,
validators=[
RegexValidator(
regex='^[0-9+]+',
message='Not a valid phone number.',
),
])
address = models.CharField(max_length=255)
class Meta:
verbose_name = 'Client'
#forms.py
class ClientForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
fields = ('username', 'password', 'email', 'name', 'surname', 'phone', 'address')
model = Client
#views.py
class HomeView(CreateView):
template_name = 'home.html'
model = Client
form = ClientForm
fields = ('username', 'password', 'email', 'name', 'surname', 'phone', 'address')
success_url = reverse_lazy('home')
After you created your own user model without password, use the set_password() method to assign a password to your user object.
Ex: your_object.set_password(<psswd>)

Categories

Resources