Multiple users and authentication - Django

Asked

Viewed 1,208 times

3

I am developing a project in Django that has two types of users: Client and Accountant. Each one is authentic and has keys that identify them differently. The Customer has as its primary key its CNPJ. The key to the counter is the composition of your CRC, CNPJ and Customer’s primary key (CNPJ). That is, we can have several counters with the same CNPJ and CRC but CNPJ (Client) different. The following image shows the Entity-Relational model of this "mini-world".

inserir a descrição da imagem aqui

My problem is: How to implement this in Django, since it allows only one user in your Usermodel?

My unfulfilled approach is as follows:

  1. I create a Userprofile that inherits from Abstractbaseuser and Permissionsmixin (set up Settings.py for this new user).

  2. I put all parameters that are common between Client and Counter in Userprofile.

  3. I create two models: Client and Counter, which inherit from Userprofile.

  4. In the counter I do the Foreignkey(Client) relationship and place attributes that only belong to the Counter - name and crc.

My question is: Given this model, what is the best way to implement these two types of users who authenticate themselves and have different primary keys?

Filing cabinet Models py.

#!/usr/bin/python
# -*- coding: utf-8 -*-

from django.db import models
from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin, UserManager)

class UserProfile(AbstractBaseUser, PermissionsMixin):

    username = models.CharField(
        'CNPJ', max_length=20, unique=True
    )

    razao_social = models.CharField(
                'Razão Social', max_length=100)

    telefone = models.CharField('Telefone',max_length=20, blank=True)
    celular = models.CharField('celular',max_length=20, blank=True)
    email = models.EmailField('E-mail', unique = True, max_length=255,)

    is_active = models.BooleanField('Esta ativo?', blank=True, default=True)
    is_staff = models.BooleanField('E da equipe?', blank=True, default=False)
    date_joined = models.DateTimeField('Data de entrada', auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'username' #Campo que e unico e referencia da hora do login
    REQUIRED_FIELDS = ['email'] #Para criar super-usuario

    def __str__(self):
        return self.username

    def get_short_name(self):
        return self.username

    def get_full_name(self):
        return str(self)

    class Meta:
        verbose_name = "Usuario"
        verbose_name_plural = "Usuarios"

#Done
class Cliente(UserProfile):

    def __str__(self):
        return self.username

    class Meta:
        verbose_name = "Cliente"
        verbose_name_plural = "Clientes"

#Done
class Contador(UserProfile):

    clientes = models.ForeignKey(Cliente, on_delete=models.CASCADE,blank = True,null=True)

    crc =  models.CharField('CRC',unique=True,  max_length=20)
    nome = models.CharField('Nome', blank= True, max_length=100)

    def __str__(self):
        return self.crc

    def get_short_name(self):
        return self.nome

    def get_full_name(self):
        return str(self)

    class Meta:
        unique_together = (("crc", "email"),)
        verbose_name = "Contador"
        verbose_name_plural = "Contadores"

I also put on the website Pastebin.com

1 answer

2


Their authentication must be via email, which is a unique attribute. So you keep the primary keys of each user type.

You can create a Profile class (Client or Counter) and then another one called Userperfil, in which you define which profile each user will have on your system. And when accessing areas where only the client or accountant has access you make the check userPerfil.objects.filter(perfil='Cliente')

class Perfil(models.CharField):
   nome = models.CharField(max_length=50)


class UserProfile(models.Model):
   user = models.ForeignKey(User)
   profile = models.ForeignKey(Perfil, on_delete=models.CASCADE)
   active = models.BooleanField(default=True)

Customer and Accountant information creates two models. Remember that the Primary-key of Django is the id, created automatically. The primary key you want in the counter will always repeat itself by breaking the normalization rules. You just relating customer within counter can retrieve the easiest information like which customer counters x have, which customers the counter y have and so on

class Cliente(models.CharField):
    cnpj = models.CharField(max_length=10)


class Contator(models.CharField):
    crc = models.CharField(max_length=4)
    cliente = models.ForeignKey(Cliente, on_delete=models.CASCADE)
  • Authentication has to be different for both models. Client by cnpj and counter by crc.

  • What is the relationship of the client and counter model with Userprofile? This "link" is missing, right?

  • The relationship is that you will associate each user to a profile (Client or counter) in this class is she who makes the call because she receives a user and a profile

  • 1

    https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html I think this solves your whole problem of working with user types

  • I’m not imagining how it works with "flags". How do I create a form that is authenticatable from a model that inherits from models.Model? (is the example of the Student class of the link you sent me)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.