Django - add user as team member in view

Asked

Viewed 43 times

0

How to allow a user to register to already become a team member through their own view in Django?

I tried it this way, but nothing happened.

py views.:

def cadastro(request):
    form = ParticipanteForm()

    if request.method == 'POST':
        form = ParticipanteForm(request.POST)
        
        if form.is_valid():
            form.save()
            request.user.is_staff = True
            return redirect('dashboard')

    return render(request, 'cadastro.html', locals())
  • how are your models.py?

  • Hi. My models look like this: 
class Participante(models.Model):
 nome = models.CharField(max_length=100)
 cpf = models.CharField(max_length=13)
 email = models.EmailField()
 dt_criacao = models.DateTimeField(auto_now=True)

 def __str__(self):
 return self.nome

 Have other models, but what I want to leave as a team member is these models there.

1 answer

1

Hello, this desired behavior is related to the existing model:

.virtualenvs/nome_do_projeto/lib/python3.7/site-Packages/Django/contrib/auth/models.py

One of the templates within this python file is as follows:

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = True

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """Send an email to this user."""
        send_mail(subject, message, from_email, [self.email], **kwargs)


Django allows you to overwrite this standard template, but you will need to create an app called "users" and then yes, in the archive py.models this app overwrite the function (app created, the list of the Settings must be updated)

is_staff = models.BooleanField(
        _('staff status'),
        default=True, #o Padrão é False
        help_text=_('Designates whether the user can log into this admin site.'),
    )

But you will copy the file and only modify one thing in it?

No... an easier way is for you to inherit it in the model:

class MeuUsuario(AbstractUser):
"""e aqui se atentar ao que pretende modificar"""
"""por exemplo, quer cadastrar email, nome e modificar a ação is_staff"""
    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)

Obviously since the name of a "username" item has been changed to name and you intend to consider it as a user field, you need to inform:

class MeuUsuario(AbstractUser):

    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)
 
    USERNAME_FIELD = 'nome' #aqui você indica o campo que predente usar como identificação do do namoe de usuário

But that’s all you can do? No... if you still want to use some other default options, you can add, for example:

class MeuUsuario(AbstractUser):

    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)
 
    USERNAME_FIELD = 'nome'
    REQUIRED_FIELDS = ['first_name', 'last_name'] #aqui você pode colocar outros campos que já existem no modelo padrão.

and end by calling the Manager

class MeuUsuario(AbstractUser):

    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)
 
    USERNAME_FIELD = 'nome'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = UsuarioManager() #aqui foi mudado o nome do modelo padrão

That’s the first step.

The second is: as some things have been changed, you need to overwrite the Manager, and so before this newly written class will have to practically copy and paste the Usermanager(Baseusermanager) which is in the same file as the Abstractuser(Abstractbaseuser, Permissionsmixin) quoted earlier:

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password, **extra_fields)

class MeuUsuario(AbstractUser):

    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)
 
    USERNAME_FIELD = 'nome'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = UsuarioManager()

But that’s all?

No, first remember that you (to avoid conflicts) changed the name of the Manager, so you have to change the name of the class you just copied.

You have also changed username for name then you need to check all the manager to avoid problems

Note also that you can remove the field extra_fields.setdefault('is_staff', False) create_user knowing that it is a user who will auto-register (this word is beautiful... must be wrong):

class UsuarioManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, **nome**, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        nome = self.model.normalize_username(nome)
        user = self.model(username=nome, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, nome, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password, **extra_fields)

class MeuUsuario(AbstractUser):

    email = models.EmailField(_('email address'), blank=True)
    nome = models.CharField('nome', max_length=15, unique=True)
    is_staff = models.BooleanField('Funcionário', default=True)
 
    USERNAME_FIELD = 'nome'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = UsuarioManager()

I think that’s all... at least as far as the question is concerned.

There you say, but I have my form... the procedure is the same, as if it were a common model, the idea here is to modify a standard action of Django so that you manipulate it according to the aesthetics you find most convenient.

=]

  • Great answer, thanks for the attention and willingness! A question: is it necessary to create another app and make the modification on itself? Could you tell me why this is happening and I can’t do it in my app already in question?

  • There’s something I’ve never tried... so I’d rather not answer so as not to confuse.

  • 1

    then, just add the line form.instance.is_staff = True, before the form.save(), in the view. It worked! : D o

Browser other questions tagged

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