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
:
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
Comentarios y valoraciones del post
Te invitamos a confirmar nuestra publicación dejando un comentario o valorándolo te estamos eternamente agradecidos.