Create Custom User Model and REST API
Updated: Dec 1, 2022
Go To Models.py and Create Custom User Class
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.models import BaseUserManager
class UserProfileManager(BaseUserManager):
def create_user(self, email, name, password=None):
if not email:
raise ValueError("User Email Is Important")
email=self.normalize_email(email)
user=self.model(email=email, name=name)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
user=self.create_user(email, name, password)
user.is_superuser=True
user.save(using=self._db)
return user
class UserProfile(AbstractBaseUser, PermissionsMixin):
email=models.EmailField(max_length=255, unique=True)
name=models.CharField(max_length=255)
is_active=models.BooleanField(default=True)
is_staff=models.BooleanField(default=True)
objects=UserProfileManager()
USERNAME_FIELD="email"
REQUIRED_FIELDS=["name"]
def get_full_name(self):
return self.name
def short_name(self):
return self.name
def __str__(self):
return self.email
Register User Model
Go To admin.py
from django.contrib import admin
from profiles_api import models
admin.site.register(models.UserProfile)
Go to Setting in last row and write this
AUTH_USER_MODEL='profiles_api.UserProfile'
Then go to vagrant's gitbash and run command for migrations
"python manage.py makemigrations profiles_api"
"python manage.py migrate"
"python manage.py runserver"
Git Commit from GitBash
command 1: git add .
command 2: git commit -am "custom user model"
command 3: git push origin
Creating Hello World REST API
Open File urls.py of project or root folder
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('profiles_api.urls'))
]
2. Open App urls.py file to create url
from django.urls import path
from profiles_api import views
urlpatterns = [
path('hello-view/', views.HelloApiVIew.as_view())
]
3. Create Hello world API. in views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class HelloApiVIew(APIView):
def get(self, request, format=None):
an_api = [
"Uses Statndard HTTP methods as function(get, post,put,delete)",
"It is similar to traditional Django view",
"Gives you control over ur application and logic",
"It mapped manually to URL's"
]
return Response({"message":"hello world", "an_api" : an_api})
4. Now go to url 127.0.0.1:8000/api/hello-view to get the object
Create serializers for the POST request
Note serializers is a feature from Django REST Framework that allows you to easily convert data input into a python objects and vice-versa. It is similar to Django forms which contains various fields to use in REST API.
If we want to add POST/UPDATE functionality to any API then we need to create serializers to receive the content that we post to the API.
Create a file serializers.py in our APP, profiles_api
from rest_framework import serializers
class HelloSerializers(serializers.Serializer):
name=serializers.CharField(max_length=10)
age = serializers.IntegerField()
4. Add POST method to APIView
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from profiles_api import serializers
class HelloApiVIew(APIView):
serializer_class = serializers.HelloSerializers
def get(self, request, format=None):
an_api = [
"Uses Statndard HTTP methods as function(get, post,put,delete)",
"It is similar to traditional Django view",
"Gives you control over ur application and logic",
"It mapped manually to URL's"
]
print("Log for ans_api",type(an_api))
return Response({"message":"hello world", "an_api" : an_api})
def post(self, request):
serializer = self.serializer_class(data=request.data)
print("Log for serializer", type(serializer))
if serializer.is_valid():
name=serializer.validated_data.get("name")
age=serializer.validated_data.get("age")
message = f"hello {name, age}"
return Response({'message' : message})
else:
return Response(serializer.errors,
status = status.HTTP_400_BAD_REQUEST
)
5. Commit code to the git
git add .
git commit -am "Creating serializers for the POST request"
git push origin
Add PUT, PATCH and DELETE functions
def put(self, request, pk=None):
"""Handling update an object"""
return Response({'method':'PUT'})
def patch(self, request, pk=None):
"""Handling partial update of an object """
return Response({'method' : 'PATCH'})
def delete(self, request,pk=None):
"""Delete an Object """
return Response({'method' : 'DELETE'})
Commit code to the git
git add .
git commit -am "Creating serializers for the POST request"
git push origin
Create a simple viewset and add a router url
Just like a APIView class , allows us to write a logic for our endpoints
However instead of defining functions for HTTP methods viewset accept function that maps to comman API object, such as list, create, retrive, update, partial_update and destroy object.
Additionally ViewSet ,
Takes care of lot of typical logic for us
Perfect for standard database operation.
Fastest way to make an API that make a database Interface.
When should we use ViewSets
Basically It is depend on personal preference, However here are some use cases where you can apply ViewSet over APIView.
A simple CRUD interface to your database.
A Quick and simple API to manage predefined objects.
Very basic custom logics, in addition to the viewset features already provided by a Django Rest Framework.
API is working with standard database structure
Lets Implement it in our project.
open views.py file in profiles_api
from rest_framework import viewsets
class HelloViewSet(viewsets.ViewSet):
"""Test API ViewSet """
def list(self, request):
"""Return a hello Message """
a_viewset = [
"uses action such as (list, create, retrive, update, partial_update)",
"Automatically map to URL's using routers",
"Provides more functionality with less code"
]
return Response({'message' : "Hello", 'a_viewset':a_viewset})
Add a URL Router in urls.py file
from django.urls import path, include
from profiles_api import views
from rest_framework.routers import DefaultRouter
router=DefaultRouter()
router.register('hello-viewset', views.HelloViewSet, base_name='hello_viewset')
"""Note: base_name is use to retrive the URL in our router """
urlpatterns = [
path('hello-view/', views.HelloApiVIew.as_view()),
path('', include(router.urls))
]
Commit code to the git
git add .
git commit -am "Creating serializers for the POST request"
git push origin
Add create, retrive, update, partial_updater, and destroy method. Open views.py
class HelloViewSet(viewsets.ViewSet):
"""Test API ViewSet """
serializer_class = serializers.HelloSerializers
def list(self, request):
"""Return a hello Message """
a_viewset = [
"uses action such as (list, create, retrive, update, partial_update)",
"Automatically map to URL's using routers",
"Provides more functionality with less code"
]
return Response({'message' : "Hello", 'a_viewset':a_viewset})
def create(self,request):
"""create a new hello world message"""
serializer=self.serializer_class(data=request.data)
if serializer.is_valid():
name=serializer.validated_data.get('name')
age=serializer.validated_data.get('age')
message=f'Hello{name, age}!'
return Response({'message' : message})
else:
return Response(serializer.errors,
status = status.HTTP_400_BAD_REQUEST)
def retrive(self, request, pk=None):
"""Handles getting an object by ID """
return Response({'http_method': 'GET'})
def update(self, request, pk=None):
"""Handles update an object"""
return Response({'http_method':'PUT'})
def partial_update(self, request, pk=None):
"""Handles partial updates"""
return Response({'http_method':'PATCH'})
def destroy(self, request, pk=None):
return Response({'http_method' : 'DELETE'})