La vue principale est une simple liste de pages paginées et je souhaite ajouter un formulaire de recherche à celui-ci.
Je pensais que quelque chose comme ça ferait l'affaire:
class MyListView(ListView, FormView):
form_class = MySearchForm
success_url = 'my-sucess-url'
model = MyModel
# ...
Mais apparemment, je me suis trompé .. et je ne trouve pas comment le faire dans la documentation officielle.
Suggestions ?
Ces réponses ont beaucoup aidé à me diriger dans la bonne direction. Merci gars.
Pour ma mise en œuvre, j'avais besoin d'une vue de formulaire qui a renvoyé une liste de réception sur Get and Post. Je n'aime pas avoir à répéter le contenu de la fonction d'obtention, mais cela avait besoin de quelques changements. Le formulaire est maintenant disponible à partir de get_queryset maintenant avec Self.Form.
from Django.http import Http404
from Django.utils.translation import ugettext as _
from Django.views.generic.edit import FormMixin
from Django.views.generic.list import ListView
class FormListView(FormMixin, ListView):
def get(self, request, *args, **kwargs):
# From ProcessFormMixin
form_class = self.get_form_class()
self.form = self.get_form(form_class)
# From BaseListView
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty and len(self.object_list) == 0:
raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
context = self.get_context_data(object_list=self.object_list, form=self.form)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
class MyListView(FormListView):
form_class = MySearchForm
model = MyModel
# ...
J'ai aussi jeté pour une solution appropriée. Mais je ne pouvais pas y trouver aucun aussi devait venir avec moi-même.
vues.py
class VocationsListView(ListView):
context_object_name = "vocations"
template_name = "vocations/vocations.html"
paginate_by = 10
def get_queryset(self):
get = self.request.GET.copy()
if(len(get)):
get.pop('page')
self.baseurl = urlencode(get)
model = Vocation
self.form = SearchForm(self.request.GET)
filters = model.get_queryset(self.request.GET)
if len(filters):
model = model.objects.filter(filters)
else:
model = model.objects.all()
return model
def get_context_data(self):
context = super(VocationsListView, self).get_context_data()
context['form'] = self.form
context['baseurl']= self.baseurl
return context
modèles.py
class Vocation(models.Model):
title = models.CharField(max_length = 255)
intro = models.TextField()
description = models.TextField(blank = True)
date_created = models.DateTimeField(auto_now_add = True)
date_modified = models.DateTimeField(auto_now = True)
created_by = models.ForeignKey(User, related_name = "vocation_created")
modified_by = models.ForeignKey(User, related_name = "vocation_modified")
class Meta:
db_table = "vocation"
@property
def slug(self):
return defaultfilters.slugify(self.title)
def __unicode__(self):
return self.title
@staticmethod
def get_queryset(params):
date_created = params.get('date_created')
keyword = params.get('keyword')
qset = Q(pk__gt = 0)
if keyword:
qset &= Q(title__icontains = keyword)
if date_created:
qset &= Q(date_created__gte = date_created)
return qset
donc, fondamentalement, j'ajoute ce morceau de code à chaque classe modèle, où je veux implémenter la fonctionnalité de recherche. En effet, les filtres pour chaque modèle doivent être préparés explicitement
@staticmethod
def get_queryset(params):
date_created = params.get('date_created')
keyword = params.get('keyword')
qset = Q(pk__gt = 0)
if keyword:
qset &= Q(title__icontains = keyword)
if date_created
qset &= Q(date_created__gte = date_created)
return qset
il prépare le filtre QSe que j'utilise pour récupérer les données du modèle
L'ajout de formulaires à l'index et les vues de la liste à l'aide de mixines est couverte de la documentation officielle .
La documentation recommande généralement de cette approche. Cela suggère de simplement écrire un peu plus de python et coder la vue manuellement.
Des réponses précédentes, voici mon prise sur les points de vue que j'ai utilisés pour afficher le formulaire sur la même page que la liste de liste:
class IndexView(FormMixin, ListView):
''' Homepage: displays list of links, and a form used to create them '''
template_name = "links/index.html"
context_object_name = "links"
form_class = LinkForm
def get_queryset(self):
return Links.objects.all()
def add_link(request):
# Sole job of this function is to process the form when POSTed.
if request.method == "POST":
form = LinkForm(request.POST)
if form.is_valid():
Links.objects.create(address=form.cleaned_data['address'])
return HttpResponseRedirect('/')
Ensuite, la dernière chose est de lier la fonction Add_Link View à l'URL d'action du formulaire et que vous êtes prêt à partir, je pense.
In Django 2.2 Vous pouvez le faire (cela fonctionne bien au moins avec un get
- Demande):
from Django.views.generic import ListView
from Django.views.generic.edit import FormMixin
from .models import Property
from .forms import SearchForm
class ListPageView(FormMixin, ListView):
template_name = 'property_list.html'
model = Property
form_class = SearchForm
queryset = Property.objects.all()
Utilisez le FormMixin
avant le ListView
. Si vous souhaitez utiliser le SearchForm
dans un TemplateView
vous pouvez le faire:
from Django.views.generic.base import TemplateView
from Django.views.generic.edit import FormMixin
from .models import Property
from .forms import SearchForm
class HomePageView(FormMixin, TemplateView):
template_name = 'home.html'
form_class = SearchForm