FormView和CreateView有什么区别

时间:2015-12-07 02:04:59

标签: django

在官方文档中, formView是一个显示表单的视图。出错时,重新显示带有验证错误的表单;成功时,重定向到新的URL。 createView是一个视图,显示用于创建对象的表单,重新显示包含验证错误的表单(如果有)并保存对象。 //(也许我的英语不够好)所以如果我想创建一个用户创建新类别的通用视图我应该使用createview而不是formview吗?我不确定,所以我尝试了两种方式,它们都给了我同样的错误:as_view()只取一个参数(给定2个)

使用表单视图:

用于添加类别

class CategoryFormView(FormView):
    form_class = CategoryForm
    template_name = 'main/add_category.html'

    def get_success_url(self):
        return self.request.build_absolute_uri(reverse('category', args=[self.object.slug]))

    def get_context_data(self, **kwargs):
        context = super(CategoryFormView, self).get_context_data(**kwargs)
        # Add any extra context data needed for form here.
        return context

with createView

#for adding category
class CategoryCreateView(CreateView):
    model = Category
    form_class = CategoryForm
    template_name = 'main/add_category.html'

    def form_valid(self, form):
      self.object = form.save(commit=False)
      #setting
      self.object.save()
      return HttpResponseRedirect(reverse('category', args=[self.object.slug]))

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
      return super(CategoryCreateView, self).dispatch(request, *args, **kwargs)

最后这是我的urls.py

url(r'^add_category/', views.CategoryCreateView.as_view, name='add-category'),

编辑:抱歉它有效,只是忘了在网址旁边添加括号,但是请告诉我createview和formview之间的区别?什么时候应该用什么?

Edit2:

def index(request):

    categories = Category.objects.order_by('likes')[:5]
    latest_posts = Post.objects.all().order_by('-created_at')
    popular_posts = Post.objects.all().order_by('-views')
    hot_posts = Post.objects.all().order_by('-score')[:25]
    context_dict = {
        'latest_posts': latest_posts,
        'popular_posts': popular_posts,
        'hot_posts': hot_posts,
        'categories': categories
    }
    return render(request, 'main/index.html', context_dict)
#for single-post page
#we use uuslug 
def post(request, slug):
    single_post = get_object_or_404(Post, slug=slug)
    single_post.views += 1  # increment the number of views
    single_post.save()      # and save it
    context_dict = {
      'single_post' :single_post,
    }

    return render(request, 'main/post.html', context_dict)
#for category page
#we use slugfield this time 
def category(request, category_name_slug):
  context_dict = {}
  try:
    category = Category.objects.get(slug=category_name_slug)
    context_dict['category_name'] = category.name

    posts = Post.objects.filter(category=category)
    context_dict['posts'] = posts
    context_dict['category'] = category
  except Category.DoesNotExist:
    pass

  return render(request, 'main/category.html', context_dict)

编辑3

urls.py

from django.conf.urls import url
from main import views
from django.core.urlresolvers import reverse
from views import *

urlpatterns = [
    url(r'^$', IndexView.as_view(), name='index'),

    #url(r'^add_post/', views.add_post, name='add_post'),
    url(r'^add_post/$', PostCreateView.as_view(), name='post-add'),

    url(r'^(?P<slug>[\w|\-]+)/edit/$', PostUpdateView.as_view(), name='post-edit'),
    url(r'^(?P<slug>[\w|\-]+)/delete/$', PostDeleteView.as_view(), name='post-delete'),


    url(r'^add_category/$', CategoryCreateView.as_view(), name='add-category'),
    url(r'^(?P<slug>[\w|\-]+)/$', PostDetailView.as_view(), name='post'),

    url(r'^category/(?P<category_name_slug>[\w\-]+)/$', CategoryDetailView.as_view(), name='category'),

]

1 个答案:

答案 0 :(得分:9)

是。你错过了函数调用:

url(r'^add_category/', views.CategoryCreateView.as_view(), name='add-category'),

至于您的其他问题,CreateViewFormView非常相似,只有CreateViewFormView的更具体的实现。

FormView真的是要处理:

  • 在GET上显示表格
  • 在POST上显示错误的表单
  • 在表单没有错误时重定向到其他页面
另一方面,

CreateViewFormView相同,但它也是如此:

  • 假设它正在处理实现ModelForm方法
  • save()表单
  • 在重定向到其他页面之前,会调用表单save()来创建模型
  • 创建的模型存储在self.object中,以便您可以在get_success_url中使用它来为创建的对象生成网址(例如,重定向到对象详细信息页面)

Classy views是检查Django基于类的视图的一个很棒的资源。以下是两个类的链接:

https://ccbv.co.uk/projects/Django/1.9/django.views.generic.edit/FormView/ https://ccbv.co.uk/projects/Django/1.9/django.views.generic.edit/CreateView/

检查form_valid方法,您将看到最大差异。

至于选择哪个使用,我认为这一切都取决于你的情况。如果您尝试通过ModelForm创建模型实例,那么CreateView可能对您更好,如果您正在做一些通用的事情,那么FormView可能更合适。

class IndexView(TemplateView):
    template_name = 'main/index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context.update({
            'latest_posts': Post.objects.all().order_by('-created_at'),
            'popular_posts': Post.objects.all().order_by('-views'),
            'hot_posts': Post.objects.all().order_by('-score')[:25],
            'categories': Category.objects.order_by('likes')[:5],
        })
        return context

class PostDetailView(DetailView):
    model = Post
    context_object_name = 'single_post'
    template_name = 'main/post.html'
    # note that these are already "slug" by default
    pk_url_kwarg = 'slug'
    slug_field = 'slug'

    def get_object(self, queryset=None):
        obj = seuper(PostView, self).get_object(queryset)
        obj.views += 1
        obj.save()
        return obj

class CategoryDetailView(DetailView):
    model = Category
    template_name = 'main/category.html'
    context_object_name = 'category'
    # note that these are already "slug" by default
    pk_url_kwarg = 'slug'
    slug_field = 'slug'

    def get_context_date(self, **kwargs):
        context = super(CategoryDetailView, self).get_context_data(**kwargs)
        context.update({
            # really no need to put category_name in context
            # as you can simply do {{ category.name }} in your template

            # you can use relations to query related data
            'posts': self.object.post_set.all()
        })
        return context