本文介绍了FormView和CreateView有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在官方文档中,formView是显示表单的视图.错误时,重新显示带有验证错误的表格;成功后,将重定向到新的URL.createView是一个视图,该视图显示用于创建对象的表单,重新显示带有验证错误的表单(如果存在)并保存该对象.//(也许我的英语还不够好)所以如果我想创建一个通用的视图,让用户创建一个新类别,我应该在formview上使用createview,对吗?我不确定,所以我尝试了两种方式,但两种方式都给我相同的错误:as_view()恰好接受了1个参数(给定2个参数)

使用表单视图:

添加类别

  class CategoryFormView(FormView):form_class = CategoryFormtemplate_name ='main/add_category.html'def get_success_url(self):返回self.request.build_absolute_uri(reverse('category',args = [self.object.slug])))def get_context_data(self,** kwargs):context =超级(CategoryFormView,self).get_context_data(** kwargs)#在此处添加表单所需的任何其他上下文数据.返回上下文 

使用createView

 #用于添加类别类CategoryCreateView(CreateView):型号=类别form_class = CategoryFormtemplate_name ='main/add_category.html'def form_valid(自我,形式):self.object = form.save(commit = False)#环境self.object.save()返回HttpResponseRedirect(reverse('category',args = [self.object.slug]))@method_decorator(需要登录)def dispatch(self,request,* args,** kwargs):返回super(CategoryCreateView,self).dispatch(request,* args,** kwargs) 

最后这是我的urls.py

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

对不起,它起作用了,只是忘了在URL旁边加上括号,但是您能告诉我createview和formview之间的区别吗?什么时候应该使用什么?

Edit2:

  def索引(请求):类别= Category.objects.order_by('喜欢')[: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,类别":类别}返回render(request,'main/index.html',context_dict)#单篇文章页面#我们使用uuslugdef post(request,slug):single_post = get_object_or_404(Post,slug = slug)single_post.views + = 1#增加视图数量single_post.save()#并保存context_dict = {'single_post':single_post,}返回render(request,'main/post.html',context_dict)#for类别页面#这次我们使用slugfielddef类别(请求,category_name_slug):context_dict = {}尝试:类别= Category.objects.get(slug = category_name_slug)context_dict ['category_name'] = category.nameposts = Post.objects.filter(category = category)context_dict ['posts'] =帖子context_dict ['category'] =类别除了Category.DoesNotExist:经过返回render(request,'main/category.html',context_dict) 

编辑3

urls.py

django.conf.urls中的

 导入URL从主要进口角度看从django.core.urlresolvers导入反向从视图导入*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 \-] +)/$',CategoryDe​​tailView.as_view(),name ='category'),] 
解决方案

是.您在以下位置缺少函数调用:

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

关于您的其他问题, CreateView FormView 非常相似,只是 CreateView FormView

的更具体的实现.

FormView 实际上是要处理的:

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

CreateView FormView 相同,除了它也执行以下操作:

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

经典视图是检查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],})返回上下文类PostDetailView(DetailView):型号=发布context_object_name ='单一帖子'template_name ='main/post.html'#请注意,这些默认情况下已经塞子"pk_url_kwarg ='子弹'slug_field ='弹头'def get_object(self,queryset = None):obj = seuper(PostView,self).get_object(queryset)obj.views + = 1obj.save()返回obj类CategoryDe​​tailView(DetailView):型号=类别template_name ='main/category.html'context_object_name ='类别'#请注意,这些默认情况下已经塞子"pk_url_kwarg ='子弹'slug_field ='弹头'def get_context_date(self,** kwargs):context =超级(CategoryDe​​tailView,self).get_context_data(** kwargs)context.update({#确实不需要将category_name放在上下文中#,因为您只需在模板中执行{{category.name}}#您可以使用关系来查询相关数据'帖子':self.object.post_set.all()})返回上下文 

In the official documentation,formView is A view that displays a form. On error, redisplays the form with validation errors; on success, redirects to a new URL.createView is A view that displays a form for creating an object, redisplaying the form with validation errors (if there are any) and saving the object.//(maybe my English isn't good enough)So if I want to make a generic view that users to create a new category I should use createview over formview right? I wasn't sure, so I tried both ways and both of them gives me same error:as_view() takes exactly 1 argument (2 given)

With form view:

for adding category

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)
   

Finally this is my urls.py

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

Edit: sorry it works, just forgot to put parenthesis next to url, but can you please tell me the difference between createview and formview? when should use what?

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)
  

Edit 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'),
    
]
解决方案

Yes. You were missing function call in:

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

As for your other question, CreateView and FormView are pretty similar, except CreateView is more specific implementation of FormView.

FormView is really meant to handle:

  • display form on GET
  • display form with errors on POST
  • redirect to a different page when form has no errors

CreateView on the other hand is identical to FormView except it does this as well:

  • it is assumed it is dealing with a ModelForm form which implements save() method
  • before redirecting to a different page, the form's save() is called which creates the model
  • the created model is stored in self.object so that you can use it in get_success_url to generate a URL for the created object (e.g. redirect to object detail page)

Classy views is an awesome resource to inspect Django class-based-views. Here are links for both classes:

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/

Check our the form_valid methods where you will see the biggest diff.

As for picking which to use, I think it all depends on your scenario. If you are trying to create model instances via ModelForm then CreateView is probably better for you and if you are doing something generic then FormView is probably a better fit.


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

这篇关于FormView和CreateView有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 13:13