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