【问题标题】:Transforming into class based-view, how and why?转换为基于类的视图,如何以及为什么?
【发布时间】:2015-12-06 12:24:39
【问题描述】:

似乎大多数人使用基于类的视图而不仅仅是无聊的功能。我通过免费的在线教程学习了 django,但他们并没有真正告诉我基于类的视图(至少我做过的那些)。 如果有人能告诉我如何将我的函数转换为基于类的视图,我将不胜感激。以及为什么它们优于功能。我对函数很满意,但不幸的是,我想了解的大多数示例都是基于类的视图。这是我的代码。

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)
#for adding category

def add_category(request):
  if request.method == 'POST':
    form = CategoryForm(request.POST)
    if form.is_valid():
      form.save(commit=True)
      return index(request)
    else:
      print form.errors
  else:
    form = CategoryForm()

  return render(request, 'main/add_category.html', {'form':form})

我尝试添加类别

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)
      # any manual settings go here
      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)

编辑::

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

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

urls.py

从 django.conf.urls 导入 url 从主要导入视图 从 django.core.urlresolvers 导入反向 从视图导入 *

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

    #url(r'^add_post/', views.add_post, name='add_post'),
    url(r'^add_post/$', login_required(CategoryFormView.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/', CategoryFormView.as_view, name='add_category'),
    url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),

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

【问题讨论】:

  • 文档中是否有您不理解的内容?你面临的问题是什么?您是否尝试过创建 CBV?留意TemplateView
  • 您好,是的,我查看了文档并感到困惑,所以我查看了onespacemedia.com/news/2014/feb/5/…,但每次尝试时仍然会出错
  • 你能把你的代码贴在这里吗?你尝试了什么。包括您遇到的错误?
  • 我得到无效的语法,认为可能是因为缩进,所以尝试了很多次但错误。另外我不确定如何处理 listview 和 detail-view,因为它们在 context_dict 中有更多
  • 您可以扩展FormView 而不是CreateView。将success_url 设置为有效的表单。覆盖 get_context_data(self, **kwargs) 以传递上下文数据。

标签: django


【解决方案1】:

不用CreateView,只需创建一个FormView

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

【讨论】:

  • 主要问题是@method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(categoryCreateView, self).dispatch(request, *args, **kwargs ) 这部分语法无效
  • @stackchange 这应该可以。错误信息到底是什么?您确认没有缩进错误吗?尝试将装饰器添加到urls.py 文件怎么样?
  • 是的,我很确定我的 url 设置正确,请看上面的内容
  • @stackchange 不,我的意思是,不要使用装饰器,而是尝试将 url - login_required(CategoryFormView.as_view()) 包装在 urls.py 文件中。
  • 它仍然给我同样的错误:as_view() 只需要 1 个参数(给定 2 个)
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2021-05-30
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 2023-02-25
  • 2010-09-29
相关资源
最近更新 更多