How to implement registration and login logics as an API using ViewSet instead of generic views in Django Rest Framework
I am new to viewset when using Django Rest Framework to create registration and login logics as an API using ViewSet instead of generic views, and exposing resources to a React standalone frontend app on a diffrent port. In a previous project where I had the possibility to use django template as frontend inside the django project, I simply used django Views to implement the registration and login logics and template by doing this:
// MyOldMethod.py
@login_required
def index(request):
return render(request,'customers/index.html')
def signup(request):
context = {}
form = UserCreationForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
user = form.save()
login(request,user)
return render(request,'customers/index.html')
context['form']=form
return render(request,'registration/signup.html',context)
And by this mean, the basic login authentication were set. Now for this case, I need to use viewset and serializer and at the end, connect the React frontend app to the django API using axios. So far I implemented, the models.py, serializer.py and api.py and the urls.py as follow in the customers app.
// models.py inside customers App
from django.db import models
from django.core.validators import RegexValidator
class Customer(models.Model):
name = models.CharField(max_length=100)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone = models.CharField(validators=[phone_regex], max_length=17, blank=True) # validators should be a list
email = models.EmailField()
activated = models.BooleanField(default=False)
message = models.CharField(max_length=300)
created_at = models.DateTimeField(auto_now_add=True)
def _str_(self):
return self.name
// serializers.py inside customers App
from rest_framework import serializers
from .models import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
// serializers.py inside customers App
from rest_framework.decorators import permission_classes
from Customer.models import Customer
from rest_framework import viewsets, permissions
from .serializers import CustomerSerializer
class CustomerViewSet(viewsets.ModelViewSet):
queryset = Customer.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = CustomerSerializer
// urls.py inside customers App
from rest_framework import routers, urlpatterns
from .api import CustomerViewSet
router = routers.DefaultRouter()
router.register('api/customer', CustomerViewSet, 'customer')
urlpatterns = router.urls
The problem with this implementation which is based on my limited understanding of viewset is that I don't know how to write the registration and login logics with viewset as I did in MyOldMethod.py . I will really appreciate any help to acheive this purpose and get me more familiar with the arcana of viewset, because among it's predefined actions (list, create, retreive, update, partial_update, destroy), I saw none that helps implement registration and login authentication and logics as I did before with generic views. Thank you in advance.
Solution 1:
You can get much information about ModelViewSet here.
When it comes to your question , there are different ways to solve it.
You can override create()
in CustomerSerializer:
class Customererializer(serializers.ModelSerializer):
# ....
def create(self, validated_data):
customer = Customer.objects.create(**validated_data)
return customer
Another solution is that you can write your own create method in your viewset class:
class CustomerViewSet(viewsets.ModelViewSet):
def create(self, request, format=None):
# create user here