Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django authentication with modelform

I have two models

from django.contrib.auth.models import User
class Vendor(models.MOdel):
    user = models.ForeignKey(User,related_name = 'vendor')
    ......................................................
    ......................................................
class Customer(models.MOdel):
    user = models.ForeignKey(User,related_name = 'customer')
    ........................................................
    .......................................................

what i want to do is enable login for a Vendor and a customer.The login url of vendor is 'vendor/login' and customer is 'customer/login'.While a vendor submit his credentials,i want to check whether the user is a vendor or not and raise a validation error.I couldn't find a way to accomplish this using django.What i basically need is something like a modelform for User which checks the user is a vendor using a queryset.But django auth doesn't have something like this.

like image 604
Sandeep Balagopal Avatar asked Jan 22 '26 13:01

Sandeep Balagopal


2 Answers

The best strategy for me is to write two Authentication Backends, one that enables the vendor authentication and another that does it for the customer.

AUTHENTICATION_BACKENDS is the settings constant giving the authorization backend tuple. here can you check the documentation about authentication backends.

Declare your implentations with the settings parameter. The order counts django will try all backends untill one is successful.

like image 72
bambata Avatar answered Jan 24 '26 05:01

bambata


You could use Django custom user model, add the type field and use it as a factory source to load Vendor/Customer objects. Such solution worked for me very well. Something to start from:

models.py

from django.contrib.auth.models import AbstractUser

TYPES = (
    ('Vendor', 'Vendor'),
    ('Customer', 'Customer'),
)


class MyUser(AbstractUser):
    type = models.CharField(max_length=10, choices=TYPES, default='Customer') 

This approach is very flexible and scales well if you need to add other types in the future. Small example of redirection approach:

class Base():
    def __init__(self, auth_user):
        self.user = auth_user

    def redirect_to(self):
        return ""

class Vendor(Base):
    def redirect_to(self):
        return "/login/vendor"

class Customer(Base):
    def redirect_to(self):
        return "/login/customer"

Then in the login view you would just dynamically create the user object:

auth_user = form.get_user()
cls = globals()[auth_user.type]
user = cls(auth_user)  # This will return either Vendor or Customer object
return HttpResponseRedirect(user.redirect_to())

You can easily create another user types by just adding new class and implementing the needed methods without even touching the rest of the code.

like image 31
matino Avatar answered Jan 24 '26 04:01

matino