es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django. Recuperando datos de un modelo relacionado para usar en un formulario.

¿Cómo puedo asociar automáticamente un usuario con un id_ticket y completar un campo en el formulario?

Formulario de ejemplo – https://i.stack.imgur.com/9YMUv.png

models.py

class Ticket(models.Model):
    ticket_id = models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')
    ticket_title = models.CharField(max_length=100)
    ticket_date_open = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name='User')

class TicketMessage(models.Model):
    ticket_mes = models.TextField(verbose_name='Message')
    ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)

forms.py

class TicketMessageForm(ModelForm):
    ticket_mes = forms.CharField(label='Answer', required=True)

    class Meta:
        model = TicketMessage
        fields = ('ticket_mes', 'ticket')

views.py

class TicketDetailView(DetailView, CreateView):
    model = Ticket
    form_class = TicketMessageForm
    ticket_message = TicketMessage
    template_name = 'support/ticket.html'
    context_object_name = 'one_ticket'
    allow_empty = False

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['ticket_message'] = TicketMessage.objects.filter()
    return context

def form_valid(self, form):
    obj = form.save(commit=False)
    obj.user = self.request.user
    return super(TicketDetailView, self).form_valid(form)

success_url = reverse_lazy('ticket_list')

Supongo que necesito tomar de alguna manera los datos de la plantilla y pasarlos a form_valid.

Intenté agregar un campo oculto donde pasé la información necesaria. Esto funciona, pero se ve incorrecto e inseguro.

<select class="d-none" name="ticket" required="" id="id_ticket">
    <option value="{{ one_ticket.ticket_id }}" selected="">{{ one_ticket.ticket_id }}</option>
</select>
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para asociar automáticamente un usuario con un id_ticket y completar un campo en el formulario, puedes utilizar el parámetro initial en la instancia del formulario para proporcionar valores iniciales a los campos del formulario.

    Primero, puedes asignar el objeto Ticket a una variable en la vista, digamos ticket. Luego, puedes pasar este objeto a la instancia del formulario y establecer su campo ticket como el valor inicial para el formulario.

    Aquí hay una versión actualizada de views.py que muestra este enfoque:

    class Ticket(DetailView, CreateView):
        model = Ticket
        form_class = TicketMessageForm
        template_name = 'support/ticket.html'
        context_object_name = 'one_ticket'
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['ticket_message'] = TicketMessage.objects.filter()
            return context
    
        def get_initial(self):
            return {'ticket': self.kwargs['pk']}  # establecer el valor inicial para el campo ticket
    
        def form_valid(self, form):
            obj = form.save(commit=False)
            obj.user = self.request.user
            obj.ticket_id = self.kwargs['pk']  # establecer el id del ticket
            obj.save()
            return super(Ticket, self).form_valid(form)
    
        success_url = reverse_lazy('ticket_list')
    

    En este ejemplo, utilizamos el método get_initial para establecer el valor inicial para el campo ticket, basado en el parámetro de URL pk. Luego, en form_valid, asignamos el usuario actual al campo user y establecemos el campo ticket_id basado en el mismo parámetro pk. Por último, guardamos el objeto y devolvemos el resultado del método form_valid del padre.

    Con este enfoque, ya no necesitas utilizar un campo oculto en el formulario para pasar el id del ticket, y el envío del formulario es más seguro.

Comments are closed.