在官方文档中, 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'),
]
答案 0 :(得分:9)
是。你错过了函数调用:
url(r'^add_category/', views.CategoryCreateView.as_view(), name='add-category'),
至于您的其他问题,CreateView
和FormView
非常相似,只有CreateView
是FormView
的更具体的实现。
FormView
真的是要处理:
CreateView
与FormView
相同,但它也是如此:
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