Home > Back-end >  how to create a API for user model in Django?
how to create a API for user model in Django?

Time:08-18

I am Trying To create a API for my custom user model to register a user and get details about current user that is logged in . I tried to Follow a tutorial but I faced 2 problems, 1.The confirmation password is not being hashed when creating a user, 2. The Get method didn't work ( I was Trying to Get User details Using the id, it didn't return any thing except bad request responce ). I hope any one can help me.

This is my models.py:

from django.db import models
from django import forms
# Create your models here.

from django.db import models
from django.contrib.auth.models import (
    AbstractUser,
    BaseUserManager,
    AbstractBaseUser
    )
from django.forms import Widget
from django.urls import reverse
class CustomUserManager(BaseUserManager):
    def create_user(self,email,password=None,is_active=True,is_staff=False,is_admin=False):
        if not email:
            raise ValueError('User Must Have Email')
        if not password:
            raise ValueError('User Must Have Password')
        user_obj = self.model(
            email = self.normalize_email(email)
        )
        user_obj.set_password(password)#change user password
        user_obj.staff = is_staff
        user_obj.admin = is_admin
        user_obj.active = is_active
        user_obj.save(using=self._db)   
        return user_obj
    def create_staffuser(self,email,password=None):
        user = self.create_user(
            email,
            password = password,
            is_staff = True
        )
        return user
    def create_superuser(self,email,password=None):
        user = self.create_user(
            email,
            password = password,
            is_staff = True,
            is_admin = True,
        )
        return user
class CustomUser(AbstractBaseUser):
    username          = models.CharField(max_length= 200)
    first_name        = models.CharField(max_length = 300)
    last_name         = models.CharField(max_length = 300)
    email             = models.EmailField(max_length=255,unique=True)   
    password          = models.CharField(max_length=100,)
    password_2        = models.CharField(max_length=100,)
    sub_to_newsletter = models.BooleanField(default=True)
    own_pc            = models.BooleanField(default=False) 
    active            = models.BooleanField(default=True)  #can login
    staff             = models.BooleanField(default=False) #staff user not superuser
    admin             = models.BooleanField(default=False) #admin / superuser
    
    USERNAME_FIELD  = 'email' #username
    #email and password is requierd by default
    REQUIRED_FIELDS = [] #python manage.py createsuperuser
    objects = CustomUserManager()

    def __str__(self):
        return self.email
    def get_full_name(self):
        return self.email
    def get_short_name(self):
        return self.email
    def has_perm(self,perm,obj=None):
        return True
    def has_module_perms(self,app_label):
        return True
    @property
    def is_staff(self):
        return self.staff
    @property
    def is_admin(self):
        return self.admin
    @property
    def is_active(self):
        return self.active
    def get_absolute_url(request):
        return reverse('')

This is my forms.py:

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField
User = get_user_model()

class UserAdminCreationForm(forms.ModelForm):
    """
    A form for creating new users. Includes all the required
    fields, plus a repeated password.
    """
    password = forms.CharField(widget=forms.PasswordInput())
    password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ['email']

    def clean(self):
        '''
        Verify both passwords match.
        '''
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        password_2 = cleaned_data.get("password_2")
        if password is not None and password != password_2:
            self.add_error("password_2", "Your passwords must match")
        return cleaned_data

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user


class UserAdminChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = User
        fields = ['email', 'password']

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

This is admin.py:

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .models import *
from .forms import *
User = get_user_model()
# Register your models here.
class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserAdminChangeForm
    add_form = UserAdminCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ['email', 'admin']
    list_filter = ['admin']
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('username','first_name','last_name','sub_to_newsletter','own_pc')}),
        ('Permissions', {'fields': ('admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password', 'password_2')}
        ),
    )
    search_fields = ['email']
    ordering = ['email']
    filter_horizontal = ()


admin.site.register(User,UserAdmin)

CodePudding user response:

I suggest that you remove password_2 from your user model. There is no reason to store the password twice. The purpose of a "confirm password" is to force the user to enter the same password twice in order to eliminate typos.

You can keep password_2 as a form field. Then add field validation to check that password and password_2 are the same.

  • Related