将函数视图转换为基于类的视图Django

时间:2019-08-10 13:09:36

标签: python django django-models django-views

我正在尝试将基于函数的视图(FBV)编写为基于类的视图(CBV),特别是CreateView。

到目前为止,我已经创建了基于类的视图,但是我使用的FBV需要一个请求和一个ID,因此不确定如何处理。

FBV可以正常工作,但作为CBV,我认为它更复杂,因为我需要更改传递到HTML的数据

我认为我不应该使用上下文,但是我不知道该如何使用

感谢您的帮助

FBV

def pages(request, id):

   obj = programas.objects.get(id=id)
   script = obj.script
   script_eng = obj.script_eng
   zip_scripts = zip(script , script_eng)
   zip_scripts_eng = zip(script_eng , script)
   random_zip = list(zip(script , script_eng))
   random_ten = random.choices(random_zip)



   context = {'title': obj.title,
              'show_date': obj.show_date,
              'script' : obj.script,
              'script_eng': obj.script_eng,
              'description': obj.description,
              'description_eng': obj.description_eng,
              'show_id':obj.show_id,
              'url': obj.url,
              'random_ten': random_ten,
              'zip_scripts' : zip_scripts,
              'zip_scripts_eng ' : zip_scripts_eng ,
               }


   return render(request, 'rtves/pages.html', context)

CBV

class PagesContentView(ListView):
   model = programas
   context_object_name = "show_info"
   template_name = 'pages/index.html'

   def pages(request, id):

          obj = programas.objects.get(id=id)
          script = obj.script
          script_eng = obj.script_eng
          zip_scripts = zip(script , script_eng)
          zip_scripts_eng = zip(script_eng , script)
          random_zip = list(zip(script , script_eng))
          random_ten = random.choices(random_zip)



          context = {'title': obj.title,
                     'show_date': obj.show_date,
                     'script' : obj.script,
                     'script_eng': obj.script_eng,
                     'description': obj.description,
                     'description_eng': obj.description_eng,
                     'show_id':obj.show_id,
                     'url': obj.url,
                     'random_ten': random_ten,
                     'zip_scripts' : zip_scripts,
                     'zip_scripts_eng ' : zip_scripts_eng ,
                      }


          return render(request, template_name, context)

URLS 运行正常

urlpatterns = [
path('about/', views.AboutView.as_view()),
path('', views.IndexView.as_view()),    
path('pages/<int:id>/', PagesContentView.as_view()),

]

页面加载正常,但是数据库没有返回任何数据。

HTML

{% if show_info %}

<h2>{{ title }}</h2>
<p>{{ description_eng | truncatewords_html:100 | safe }}</p>
    <p> Number of words: {{ script |wordcount }} </p>

{% endif %}


{% for rand in random_ten %}
    <p style="padding: 20px;text-align: left;color:#3d6cdd; line-height: 1.3;"> 
    {{ rand.0 |truncatewords:30 }}</p>
{% endfor %}

如果我使用 {{show_info}} {{show_info.0}} ,我会返回一个查询集,返回的是函数“ title”的第一行:obj .title,但与ID不匹配

1 个答案:

答案 0 :(得分:2)

您在这里拥有的不是ListView,而是DetailView。您可以将其实现为:

from django.views.generic import DetailView
import random

class PagesContentView(DetailView):
    model = programas
    context_object_name = 'obj'
    pk_url_kwarg = 'id'
    template_name = 'pages/index.html'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        zip_scripts = list(zip(self.object.script , self.object.script_eng))
        context.update(
            zip_scripts=zip_scripts
            zip_scripts_eng = zip(self.object.script_eng , self.object.script)
            random_ten=random.choices(zip_scripts)
        )
        return context

因此,我们在此处指定URL路径中的主键是'id',而不是'pk',并且我们将对象传递为'obj'

在您的模板中,您可以使用以下方法呈现该图片:

<h2>{{ obj.title }}</h2>
<p>{{ obj.description_eng | truncatewords_html:100 | safe }}</p>
    <p> Number of words: {{ obj.script |wordcount }} </p>

{% endif %}


{% for rand in random_ten %}
    <p style="padding: 20px;text-align: left;color:#3d6cdd; line-height: 1.3;"> 
    {{ rand.0 |truncatewords:30 }}</p>
{% endfor %}

请注意,random_ten将包含单个2元组,而不是2元组的迭代。您可能正在寻找random.sample function [Python-doc]

模型通常在CamelCase中具有单数名称,因此您可以考虑将模型重命名为Program,而不是 programmas 。在URL路径中,主键通常命名为pk,而不是id。这样,您可以删除pk_url_kwargs = 'id'行。

最后,按照模板中的指定,通常不会单独传递每个对象属性,而只是传递一个对象,然后将该对象呈现在模板中。