Relationship Problems between "Table" and Django User

Asked

Viewed 57 times

1

I am working with Django to develop an application for a Help Desk, I have the following situation:

I have a table named "Unit" that will be the table responsible for separating my systems into 4 or more units.

My problem is, that users need to be associated to a drive through a foreign key. But I’m not finding a way to make this association.

I can "link" each unit to a user if I register the user, then update the registration by selecting the units, but in the registration form also appear the units to be selected, they go to the view by POST, but do not associate with the user after save.

My Drive and User Templates

# arquivo: core.models.py

class Unidade(models.Model):

    nome = models.CharField(max_length=100)
    endereco = models.CharField(max_length=200)
    telefone = models.CharField(max_length=20)

    class Meta:
        verbose_name_plural = "Unidades"

    def __str__(self):
        return self.nome

class User(AbstractBaseUser, PermissionsMixin, models.Model):

    email = models.EmailField(max_length=255, unique=True)
    nome = models.CharField(max_length=50)
    sobrenome = models.CharField(max_length=100)
    nascimento = models.DateField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    unidade = models.ManyToManyField('Unidade')
    timestamp = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return self.email

    def get_full_name(self):
        return f"{self.nome} {self.sobrenome}"

    def get_short_name(self):
        return self.nome

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

My templates for creating and updating users.

# arquivo: accounts.forms.py

User = get_user_model()

class SignupUserForm(UserCreationForm, forms.Form):

    class Meta:
        model = User
        fields = ('nome', 'sobrenome', 'email', 'nascimento', 'is_active', 'is_staff', 'is_admin',
                  'password1', 'password2', 'unidade')
        widgets = {
            'nome': forms.TextInput(attrs={'type':'text'}),
            'sobrenome': forms.TextInput(attrs={'type':'text'}),
            'email': forms.TextInput(attrs={'class': 'col-12', 'type':'email', 'placeholder':'Digite seu e-mail'}),
            'nascimento': forms.DateInput(attrs={'class':'col-10'}, format='%d/%m/%Y'),
            'unidade': forms.SelectMultiple(attrs={'class':'col-12'})
        }

class UpdateUserForm(UserChangeForm, forms.Form):    

    class Meta:
        model = User
        fields = ('nome', 'sobrenome', 'email', 'nascimento', 'is_active', 'is_staff', 'is_admin',
                  'unidade')
        widgets = {
            'nome': forms.TextInput(attrs={'type':'text'}),
            'sobrenome': forms.TextInput(attrs={'type':'text'}),
            'email': forms.TextInput(attrs={'class': 'col-12', 'type':'email', 'placeholder':'Digite seu e-mail'}),
            'nascimento': forms.DateInput(attrs={'class':'col-10'}, format='%d/%m/%Y'),
            'unidade': forms.SelectMultiple(attrs={'class':'col-12'})
        }

My views to render the page and process the form.

# arquivo: accounts.views.py

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from accounts.forms import SignupUserForm, UpdateUserForm
from core.models import User


@login_required
def signup(request):
    if request.method == 'POST':
        if request.user.is_admin:
            form = SignupUserForm(request.POST)

            if form.is_valid():
                form.save()
                return redirect('/usuarios')
        else:
            return redirect('/')
    else:
        if not request.user.is_admin:
            return redirect('/')
        form = SignupUserForm()
    template_name = 'registration/register.html'
    return render(request, template_name, {'form':form})

@login_required
def updateuser(request, id):
    template_name = 'registration/atualizar.html'
    if request.method == 'POST':
        usuario = get_object_or_404(User, pk=id)
        form = UpdateUserForm(request.POST, instance=usuario)
        if form.is_valid():
            form.save()
            return redirect('/usuarios')
        else:
            return render(request, template_name, {'error':form.errors, 'form': form})
    else:
        usuario = get_object_or_404(User, pk=id)
        form = UpdateUserForm(instance=usuario)
        return render(request, template_name, {'form':form})

My template

{% extends 'base.html' %}

{% block title %}Cadastro de Usuários - Django Desk{% endblock %}

{% block content %}

{% load crispy_forms_tags %}

<style type="text/css">
    ::-webkit-scrollbar-track {
        background-color: #F4F4F4;
    }
    ::-webkit-scrollbar {
        width: 6px;
        background: #F4F4F4;
    }
    ::-webkit-scrollbar-thumb {
        background: #dad7d7;
    }
    .selectmultiple {
        width: 800px !important;
    }
</style>

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item" aria-current="page"><a href="/">Home</a></li>
        <li class="breadcrumb-item" aria-current="page">
            <a href="/usuarios">Usuários</a>
        </li>
        <li class="breadcrumb-item active" aria-current="page">Cadastro</li>
    </ol>
</nav>

<div class="row">
    <div class="col-12 col-sm-10 col-md-8 col-lg-6">
        <form method="POST">
            <div class="h4 text-center">Cadastro - DjangoDesk</div>
                {% csrf_token %}
                <input type="hidden" name="next" value="{{next}}">
                <div class="form-row">
                    <div class="form-group col-md-6 mb-0">
                        {{ form.nome|as_crispy_field }}
                    </div>
                    <div class="form-group col-md-6 mb-0">
                        {{ form.sobrenome|as_crispy_field }}
                    </div>
                </div>
                {{ form.email|as_crispy_field }}
                <div class="form-row">
                    <div class="form-group col-md-6 mb-0">
                        {{ form.nascimento|as_crispy_field }}
                        <small id="passwordHelpBlock" class="form-text text-muted">
                            Seguir o formato <span class="font-italic">"dia/mês/ano"</span>
                        </small>
                    </div>
                    <div class="form-group col-md-6 mb-0">
                        {{ form.is_active|as_crispy_field }}
                        {{ form.is_staff|as_crispy_field }}
                        {{ form.is_admin|as_crispy_field }}
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6 mb-0">
                        {{ form.password1|as_crispy_field }}
                    </div>
                    <div class="form-group col-md-6 mb-0">
                        {{ form.password2|as_crispy_field }}
                    </div>
                </div>
                {{ form.unidade|as_crispy_field }}
            <input type="submit" value="Entrar" class="btn btn-primary">
        </form>
     </div>
</div>

{% endblock %}

Visualization template:

{% extends 'base.html' %}

{% block title %}Lista de Usuários - Django Desk{% endblock %}

{% block content %}

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item" aria-current="page"><a href="/">Home</a></li>
        <li class="breadcrumb-item" aria-current="page"><a href="/usuarios">Usuarios</a></li>
        <li class="breadcrumb-item active" aria-current="page">Visualizar Usuário</li>
    </ol>
</nav>
<div class="row">
    <table class="table table-responsive talbe-bordered">
        {% if usuario %}
        <tr>
            <td>Nome completo:</td>
            <td>{{usuario.get_full_name}}</td>
            <td>Ativo:</td>
            <td>
                {% if usuario.is_active %}
                    <span class="text-success ml-3"><i class="fas fa-check-circle"></i></span>
                {% else %}
                    <span class="text-danger ml-3"><i class="fas fa-times-circle"></i></span>
                {% endif %}
            </td>
        </tr>
        <tr>
            <td>E-mail:</td>
            <td>{{usuario.email}}</td>
            <td>Gestor:</td>
            <td>
                {% if usuario.is_staff %}
                    <span class="text-success ml-3"><i class="fas fa-check-circle"></i></span>
                {% else %}
                    <span class="text-danger ml-3"><i class="fas fa-times-circle"></i></span>
                {% endif %}
            </td>
        </tr>
        <tr>
            <td>Data de Nascimento:</td>
            <td>{{usuario.nascimento}}</td>
            <td>Administrador:</td>
            <td>
                {% if usuario.is_admin %}
                    <span class="text-success ml-3"><i class="fas fa-check-circle"></i></span>
                {% else %}
                    <span class="text-danger ml-3"><i class="fas fa-times-circle"></i></span>
                {% endif %}
            </td>
        </tr>
        <tr class="tr-border">
            <td>Unidades:</td>
            <td>
                {% if usuario.unidade.all %}
                    <ul>
                        {% for unidade in usuario.unidade.all %}
                            <li>{{unidade}}</li>
                        {% endfor %}
                    </ul>
                {% endif %}
            </td>
        </tr>
        {% endif %}
    </table>
</div>

{% endblock %}

Every form works, I can register users, I can update users, just this simple field unidade that in the registration on my page users view shows no information, only after I update the user registration by selecting again the units.

Does anyone know what can cause it?

1 answer

1


Well, I’m a beginner in Django so I’ll forgive myself for making these banal mistakes. But I found the answer. It turns out that Django when using the form.save(commit=False) it does not save what is related as 'Manytomanyfield', in this case need to use the form.save_m2m() shortly after the form.save(), but it is necessary to use the form.save(commit=False). Below the solution of my file problem accounts/views.py:

# arquivo: accounts/views.py

@login_required
def signup(request):
    if request.method == 'POST':
        if request.user.is_admin:
            form = SignupUserForm(request.POST)
            if form.is_valid():
                obj = form.save(commit=False) # Esta adição.
                obj.save() # Está adição
                form.save_m2m() # e Esta adição, fizeram toda a diferença nos resultados.
                return redirect('/usuarios')
        else:
            return redirect('/')
    else:
        if not request.user.is_admin:
            return redirect('/')
        form = SignupUserForm()
    template_name = 'registration/register.html'
    return render(request, template_name, {'form':form})

Browser other questions tagged

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