python - 将函数视图转换为基于类的视图 Django
问题描述
我正在尝试将基于函数的视图(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 不匹配
解决方案
你在这里拥有的不是一个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
函数 [Python-doc]。
模型通常在 中具有单数名称CamelCase
,因此您可以考虑将模型重命名为Program
,而不是。在 URL 路径中,主键通常命名为programmas
pk
,而不是id
。通过这样做,您可以删除该pk_url_kwargs = 'id'
行。
最后,正如模板中所指定的,您通常不会单独传递每个对象属性,而只是传递一个对象,然后在模板中呈现该对象。
推荐阅读
- javascript - 将点击事件绑定到输入元素
- java - 我尝试制作 javax.ws.rs.core.Response 时 servicemix 中的异常
- xml - XML 中的 pad、pad-front 函数
- python - 在另一个模块中使用 python 方法
- ios - 编译错误:kFirLoggerSwizzler 引用自
- macos - MacOS 中的键盘记录器
- javascript - GraphQL 类型:什么是正确的分桶?
- azure - 如何在 azure 中重命名多个 VM 主机名\如何从具有不同主机名的自定义映像部署多个 VM 实例
- ios - iOS:通过单击按钮增加动画
- sql - 日期或字符串类型为 bigint