Im essayant d'apprendre des vues basées sur la classe, pour une vue de détail ou de liste n'est pas si compliquée.
J'ai un formulaire de recherche et je veux juste voir si j'envoie une requête pour afficher les résultats.
Voici le code de la fonction (n'est pas le mien, provient d'un livre Django):
def search_page(request):
form = SearchForm()
bookmarks = []
show_results = False
if 'query' in request.GET:
show_results = True
query = request.GET['query'].strip()
if query:
form = SearchForm({'query': query})
bookmarks = Bookmark.objects.filter(title__icontains=query)[:10]
show_tags = True
show_user = True
if request.is_ajax():
return render_to_response("bookmarks/bookmark_list.html", locals(), context_instance=RequestContext(request))
else:
return render_to_response("search/search.html", locals(), context_instance=RequestContext(request))
Ignorant le fait ajax (juste pour faciliter le problème pour l'instant), comment puis-je traduire cela en vues basées sur les classes?
J'ai rapidement essayé quelque chose comme ça:
class SearchPageView(FormView):
template_name = 'search/search.html'
def get(self, request, *args, **kwargs):
form = SearchForm()
self.bookmarks = []
self.show_results = False
if 'query' in self.request.GET:
self.show_results = True
query = self.request.GET['query'].strip()
if query:
form = SearchForm({'query': query})
self.bookmarks = Bookmark.objects.filter(title__icontains=query)[:10]
return super(SearchPageView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(SearchPageView, self).get_context_data(**kwargs)
context.update({
'show_tags': True,
'show_user': True,
'show_results': self.show_results,
'bookmarks': self.bookmarks
})
return context
Ne fonctionne pas, j'obtiens un: "L'objet 'NoneType' n'est pas appelable"
Très bien, j'ai commencé aujourd'hui avec ce genre de choses.
Alors, quelle est la façon de créer une vue basée sur la classe qui peut gérer une requête get (et une publication aussi si nécessaire)?
J'ai un autre exemple:
@render_to('registration/register.html')
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return HttpResponseRedirect('/accounts/register/success/')
else:
form = RegistrationForm()
return locals()
Serait-ce "transformé" de la même manière que le premier? Ou étendent-ils des vues différentes?
Je suis beaucoup confus. Je ne sais pas si le premier est ProcessFormView et le second FormView ou quoi.
Merci.
EDIT: Solution que j'ai terminée avec:
class SearchPageView(FormView):
template_name = 'search/search.html'
def get(self, request, *args, **kwargs):
self.bookmarks = []
self.show_results = False
form = SearchForm(self.request.GET or None)
if form.is_valid():
self.show_results = True
self.bookmarks = Bookmark.objects.filter(title__icontains=form.cleaned_data['query'])[:10]
return self.render_to_response(self.get_context_data(form=form))
def get_context_data(self, **kwargs):
context = super(SearchPageView, self).get_context_data(**kwargs)
context.update({
'show_tags': True,
'show_user': True,
'show_results': self.show_results,
'bookmarks': self.bookmarks
})
return context
Je laisse ceci ici à quelqu'un avec la même question :)
Le comportement par défaut de la classe FormView
consiste à afficher un formulaire indépendant pour les demandes GET
et à lier le formulaire pour POST
(ou PUT
) demandes. Si le formulaire lié est valide, le form_valid
est appelée, qui redirige simplement vers l'URL de réussite (définie par le success_url
l'attribut ou get_success_url
méthode.
Cela correspond assez bien à l'exemple. Vous devez remplacer le form_valid
méthode pour créer la nouvelle User
, avant d'appeler la méthode superclasse pour rediriger vers l'URL de réussite.
class CreateUser(FormView):
template_name = 'registration/register.html'
success_url = '/accounts/register/success/'
form_class = RegistrationForm
def form_valid(self, form):
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return super(CreateUser, self).form_valid(form)
Votre premier exemple ne correspond pas si bien au flux de FormView
, car vous ne traitez pas un formulaire avec des données POST
et vous ne faites rien lorsque le formulaire est valide.
Je pourrais essayer d'étendre TemplateView
et de mettre toute la logique dans get_context_data
. Une fois que cela fonctionne, vous pouvez factoriser le code qui analyse les données GET et renvoie les signets dans sa propre méthode. Vous pouvez envisager d'étendre ListView
, mais je ne pense pas qu'il y ait un réel avantage, sauf si vous souhaitez paginer les résultats.
Remarque, une réponse ici ( Mise à jour des données de contexte dans la méthode FormView form_valid? ) a résolu ce problème comme ceci:
class ContextFormView(FormView):
template_name = 'some_template.html'
success_url = '...'
form_class = ClassOfTheForm
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(**kwargs)
context['form'] = form
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
return self.form_valid(form, **kwargs)
else:
return self.form_invalid(form, **kwargs)
def form_invalid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = False
return self.render_to_response(context)
def form_valid(self, form, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = form
# here you can add things like:
context[show_results] = True
return self.render_to_response(context)
Cela a fonctionné parfaitement pour moi. (même problème que dans cette question)
Comme indiqué ci-dessus, ce n'est pas ma solution, si vous voulez donner des crédits à quelqu'un, allez à la réponse dans le lien et donnez à cette personne les crédits! ( Mise à jour des données de contexte dans la méthode FormView form_valid? )