How to assign the PK of the logged-in user in Django to an FK in the model?

Asked

Viewed 515 times

1

Hello, what I am trying to do is basically the following, I have in my application a Model called 'Shopping', and one of the fields of this Model is the user who registered the purchase, I want each user logged in the application see only the records that he himself made, and as to add a record has to be logged in, I want the system to automatically link the user’s Primarykey to the Foreignkey of the Purchase record, what I have so far is more or less that:

filing cabinet models.py:

from django.db import models
from django.core.validators import MinValueValidator
from django.conf import settings


class Compras(models.Model):
    nome = models.CharField(max_length=50)
    descricao = models.TextField()
    valor = models.DecimalField(max_digits=7, decimal_places=2, validators=[MinValueValidator(0.0)])
    data = models.DateField()
    parcelas = models.IntegerField(blank=True, null=True, validators=[MinValueValidator(0)])
    ususario = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)

Filing cabinet views.py:

from .models import Compras, Vendas
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.base import TemplateView


class CreateCompra(LoginRequiredMixin, CreateView):
    model = Compras
    fields = ['nome', 'descricao', 'valor', 'data', 'parcelas', 'ususario']
    success_url = reverse_lazy('tela_inicial')

Template:

{% extends 'base.html' %}
{% load bootstrap %}
{% block title %}PatchApp - Nova Compra{% endblock %}
{% block main %}
<form method="post">
    {% csrf_token %}
    {{ form|bootstrap }}
    <button class="btn btn-success" type="submit">Salvar</button>
    <a type="button" href="{% url 'tela_inicial' %}" class="btn btn-primary">Começo</a>
    <a type="button" href="{% url 'compras_lista' %}" class="btn btn-info">Lista</a>
</form>
{% endblock %}

How is it appearing: Formulário completo. The user field shows all system users: campo usuario

This way appears a list of all users for me to choose one, but as I said, I want this field not to appear, and that it be filled automatically with the user who is already logged in, how can I do this?

  • Try to provide more subsidies to those who want to help, try to understand the context, for example: where is appearing "a list with all users"? And the template code? You matter TemplateView and uses CreateView pq?

  • In vdd I have several views in this app, and at the time of copying the code was missing a few Imports, I put now tbm the template, q basically is just the form that comes ready from the view, and put some images of how is appearing.

  • Okay, how about trying to fit in to that end?

  • Where are you setting the template in the view? Where are you setting the form class in the view?

  • From what I understood from the documentation, the Django template automatically takes app/classe_form.html, and tbm generates the form through Fields = ['fields'], so I didn’t put it, but next time I’ll pay more attention to it, thank you.

  • On this last comment, think of python’s zen: "Explicit is better than implicit" :-)

Show 1 more comment

1 answer

0


Although your question is not clear enough for me, I will try to answer with what I understand. You do not show your form definition, but what you need to do is delete the field usuario, so your form should look like this:

Forms.py

class ComprasCreateForm(forms.ModelForm):
    class Meta:
        model = Compras
        exclude = ('usuario',)

    def __init__(self, *args, **kwargs):
        self.usuario = kwargs.pop('usuario')
        super(ComprasCreateForm, self).__init__(*args, **kwargs)

In the view you need to create a key in kwargs for the server that must be "captured" through the request, your view should look like this:

class CreateCompra(LoginRequiredMixin, CreateView):
    model = Compras
    form_class = ComprasCreateForm
    success_url = reverse_lazy('tela_inicial')

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.usuario = self.request.user
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())

    # Aqui vc cria a chave usuario em kwargs 
    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super(CreateCompra, self).get_form_kwargs(*args, **kwargs)
        kwargs['usuario'] = self.request.user
        return kwargs

With appropriate adaptations to its context, it should work.

Browser other questions tagged

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