2

I built a listview which works fine and gives me exactly what I want.

In the template of this ListView I declared a form that points to a CreateView. The form is like so,

{% if user.is_authenticated %}
<form action="{% url 'post_wall' %}" method="POST">
    {% csrf_token %}
    <input type='text' name='body' />
    <input type='hidden' name='from_user' value='{{ user.id }}' />
    <input type='hidden' name='to_user' value='{{ to_user }}' />
    <input type='submit' value='POST'/>
</form>
{% endif %}

the post_wall url corresponds to

url(r'accounts/post_wall', WallCreate.as_view(), name='post_wall'),

The url which contains the form is

url(r'accounts/wall/(?P<slug>\w+)/$', WallList.as_view(), name='wall'),

This calls the CreateView,

class WallCreate(CreateView):
    model = WallPost

    def get_success_url(self):
        url = reverse('wall', kwargs={'slug': request.POST.to_user})
        return HttpResponseRedirect(url)

This gives me a

TemplateDoesNotExist at /accounts/post_wall
users/wallpost_form.html

Shouldn't this be working properly as a post is sent to a CreateView? Or have I misunderstood something about CBVs?

4

1 回答 1

9

是的,但所有的表格过程都必须由ListView自己完成。这很简单,考虑到您可以从ModelFormMixin. 您只需要一个 url(到列表视图)。该模板将如下所示:

{% if user.is_authenticated %}
<form action="" method="POST">
    {% csrf_token %}
    {{ form }}
    <input type='submit' value='POST'/>
</form>
{% endif %}

而你的观点:

from django.views.generic.list import ListView
from django.views.generic.edit import ModelFormMixin

class ListWithForm(ListView, ModelFormMixin):
    model = MyModel
    form_class = MyModelForm

    def get(self, request, *args, **kwargs):
        self.object = None
        self.form = self.get_form(self.form_class)
        # Explicitly states what get to call:
        return ListView.get(self, request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # When the form is submitted, it will enter here
        self.object = None
        self.form = self.get_form(self.form_class)

        if self.form.is_valid():
            self.object = self.form.save()
            # Here ou may consider creating a new instance of form_class(),
            # so that the form will come clean.

        # Whether the form validates or not, the view will be rendered by get()
        return self.get(request, *args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        # Just include the form
        context = super(ListWithForm, self).get_context_data(*args, **kwargs)
        context['form'] = self.form
        return context
于 2013-09-06T19:27:22.227 回答