Django - Filter queryset into a form using a value present in the view

Asked

Viewed 249 times

0

I am creating this site where the first step of the user is to create the company he works for:

''''models.py'''
class Empresa(models.Model):
    cnpj = models.CharField(unique=True, max_length=20, primary_key=True)
    nomeFantasia = models.CharField(max_length=40)
    razaoSocial = models.CharField(max_length=40)
    cep = models.CharField(max_length=9)
    telefone = models.CharField(max_length=12)
    email=models.CharField(max_length=60)

'''forms.py'''
class EmpresaForm(forms.ModelForm):
    cnpj = forms.CharField()       
    nomeFantasia = forms.CharField()
    razaoSocial = forms.CharField()
    telefone = forms.CharField()
    email = forms.CharField()

    class Meta:
        model = Empresa
        fields = ('cnpj', 'nomeFantasia', 'razaoSocial', 'telefone', 'email')

'''views.py'''
def cadastrarEmpresa(request):
    context = {}
    
    empresa_form = EmpresaForm(request.POST or None)
    if empresa_form.is_valid():
        request.session['cnpj'] = empresa_form.cleaned_data['cnpj']
        obj = empresa_form.save()
        obj.save()
        empresa_form = Empresa()
        return redirect("/accounts/register")

    context['empresa_form'] = empresa_form
    return render(request, 'cadastro-empresa.html', context)

In the view is being used Session to store the company’s cnpj, which will be used in the second part, which is to register an employee who would 'manage' the company on the site

'''models.py'''
class Funcionario(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True, max_length=60)
    nome = models.TextField(max_length=35)
    cpf = models.TextField(unique=True, primary_key=True)
    '''Campos custom user'''
    empresa = models.ForeignKey(Empresa, default=None, blank=True, null=True, on_delete=models.CASCADE)

'''forms.py'''
class RegistrarionForm(UserCreationForm):
    nome = forms.CharField()
    cpf = forms.CharField()
    email = forms.EmailField()
    is_admin = forms.BooleanField(disabled=True, initial=True)
    password1 = forms.CharField(widget=forms.PasswordInput()
    password2 = forms.CharField(widget=forms.PasswordInput()
    empresa = forms.ModelChoiceField(disabled=True, queryset=Empresa.objects.all())
    class Meta:
        model = Funcionario
        fields = ("nome", "cpf", "email", "is_admin", "password1", "password2")

'''views.py'''
def register(request):
    context = {}

    empresa_cnpj = request.session.get('cnpj')
    if request.POST:
        form = RegistrarionForm(request.POST)
        if form.is_valid():
            form.save()
            email = form.cleaned_data.get('email')
            cpf = form.cleaned_data.get('cpf')
            raw_password = form.cleaned_data.get('senha1')
            funcionario = authenticate(email=email, cpf=cpf,password=raw_password)
            login(request, funcionario)
            return redirect("/home")
        else:
            context['registration_form'] = form
    else:
        form = RegistrarionForm()
        context['registration_form'] = form

    return render(request, 'registration/register.html', context)

There is a 1:N relationship between company and employees, so the employee only accesses that of the company in which he works

Doubt here is how to pass the empresa_cnpj in the employee’s.py views for

empresa = forms.ModelChoiceField(disabled=True, queryset=Empresa.objects.all()) where it would be used as a filter for something like

empresa = forms.ModelChoiceField(disabled=True, queryset=Empresa.objects.filter(cnpj=cnpj))

1 answer

0


You don’t need to pass this on to RegistrarionForm. As the CNPJ is unique you can get the object that represents the company in your view and associate it with the employee you created with the Form.

def register(request):
    context = {}

    empresa_cnpj = request.session.get('cnpj')
    if request.POST:
        form = RegistrarionForm(request.POST)
        if form.is_valid():
            funcionario = form.save()
            funcionario.empresa = Empresa.objects.get(cnpj=empresa_cnpj)
            funcionario.save()
            login(request, funcionario)
            return redirect("/home")
        
        context['registration_form'] = form
    else:
        form = RegistrarionForm()
        context['registration_form'] = form

    return render(request, 'registration/register.html', context)

One thing I realized: you don’t need to define the fields of a Form, if you are using a ModelForm with class Meta and the attribute fields (you’ve already set these fields on your own Model; and that’s why you’re using the ModelForm). Finally, I noticed some inconsistencies in the code, such as the standard of naming variables and functions, and I recommend reading the PEP8 :)

  • 1

    Thanks for the answer and tips, Murilo. Another mistake I realized was the disabled=True in the field empresa of the Forms.

Browser other questions tagged

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