Saltar al contenido

Django combina DetailView y FormView

Este artículo fue aprobado por nuestros expertos para garantizar la exactitud de nuestro tutorial.

Solución:

Una solución sería usar mixins, según el comentario anterior de los reflectores.

Otro enfoque es tener dos vistas separadas, una DetailView y el otro un FormView. Luego, en la plantilla para el primero, muestre el mismo formulario que está usando en el segundo, excepto que no dejará el action attribute vacío; en su lugar, establézcalo en la URL del FormView. Algo parecido a esto (tenga cuidado con cualquier error ya que estoy escribiendo esto sin ninguna prueba):

En views.py:

class MyDetailView(DetailView):
    model = MyModel
    template_name = 'my_detail_view.html'

    def get_context_data(self, **kwargs):
        context = super(MyDetailView, self).get_context_data(**kwargs)
        context['form'] = MyFormClass
        return context

class MyFormView(FormView):
    form_class = MyFormClass
    success_url = 'go/here/if/all/works'

En my_detail_view.html:



form

En urls.py:

# ...
url('^my_model/(?Pd+)/$', MyDetailView.as_view(), name='my_detail_view_url'),
url('^my_form/$', require_POST(MyFormView.as_view()), name='my_form_view_url'),
# ...

Tenga en cuenta que el require_POST decorador es opcional, en el caso de que no desee el MyFormView ser accesible por GET y desea que solo se procese cuando se envíe el formulario.

Django también tiene una documentación bastante extensa sobre este problema.

https://docs.djangoproject.com/en/1.8/topics/class-based-views/mixins/#using-formmixin-with-detailview

Aconsejan hacer 2 vistas diferentes y que la vista detallada se refiera a la vista del formulario en la publicación.

Actualmente estoy viendo si este truco podría funcionar:

class MyDetailFormView(FormView, DetailView):
    model = MyModel
    form_class = MyFormClass
    template_name = 'my_template.html'

    def get_context_data(self, **kwargs):
        context = super(MyDetailFormView, self).get_context_data(**kwargs)
        context['form'] = self.get_form()
        return context

    def post(self, request, *args, **kwargs):
        return FormView.post(self, request, *args, **kwargs)

Utilizando FormMixin

views.py

from django.contrib.auth import get_user_model
from django.core.urlresolvers import (
    reverse_lazy
    )
from django.http import Http404
from django.shortcuts import (
    render,
    redirect
    )
from django.views.generic import (
    DetailView,
    FormView,
    )
from django.views.generic.edit import FormMixin    

from .forms import SendRequestForm


User = get_user_model()  


class ViewProfile(FormMixin, DetailView):

    model = User
    context_object_name = 'profile'
    template_name = 'htmls/view_profile.html'
    form_class = SendRequestForm

    def get_success_url(self):
        return reverse_lazy('view-profile', kwargs='pk': self.object.pk)

    def get_object(self):
        try:
            my_object = User.objects.get(id=self.kwargs.get('pk'))
            return my_object
        except self.model.DoesNotExist:
            raise Http404("No MyModel matches the given query.")

    def get_context_data(self, *args, **kwargs):
        context = super(ViewProfile, self).get_context_data(*args, **kwargs)
        profile = self.get_object()
        # form
        context['form'] = self.get_form()
        context['profile'] = profile
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)    

    def form_valid(self, form):
    #put logic here
        return super(ViewProfile, self).form_valid(form)

    def form_invalid(self, form):
    #put logic here
        return super(ViewProfile, self).form_invalid(form)

formularios.py

from django import forms 

class SendRequestForm(forms.Form):

    request_type = forms.CharField()

    def clean_request_type(self):
        request_type = self.cleaned_data.get('request_type')
        if 'something' not in request_type:
            raise forms.ValidationError('Something must be in request_type field.')
        return request_type

urls.py

urlpatterns = [
    url(r'^view-profile/(?Pd+)', ViewProfile.as_view(), name='view-profile'),
]

plantilla

username -object.username
id -object.id
% csrf_token % form

Comentarios y valoraciones del post

Te invitamos a confirmar nuestra publicación dejando un comentario o valorándolo te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *