为了完成小姐姐安排的打分系统,又熬了一个小时的夜补充视图与模板

举报
梦想橡皮擦 发表于 2021/08/26 08:41:03 2021/08/26
【摘要】 橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起进入 Django 世界。 十三、视图与模板第十二篇博客已经初步构建好了后台管理页面,接下来继续对 Django 的视图与模板进行学习。 13.1 打分系统的视图Django 中每一个页面都是通过视图进行展示的,而视图背后对应的都是 Python 中的函数或者类中的方法,在 Django 中通过 URLconfs 进行视图匹配。这里涉及一...

橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起进入 Django 世界。

十三、视图与模板

第十二篇博客已经初步构建好了后台管理页面,接下来继续对 Django 的视图与模板进行学习。

13.1 打分系统的视图

Django 中每一个页面都是通过视图进行展示的,而视图背后对应的都是 Python 中的函数或者类中的方法,在 Django 中通过 URLconfs 进行视图匹配。这里涉及一个新的概念,叫做 URL 模式字符串,对应的浏览器地址栏里面的 /aaa/bbb/ccc 这类内容。

scoring/views.py 文件中添加如下代码,分别是 3 个视图,其中部分数据为测试用数据。

# 打分系统首页
def index(request):
    return HttpResponse("小姐姐打分系统")

# 客户详情&打分页面
def detail(request, _id):
    return HttpResponse(f"客户ID为{_id}")

# 客户分数查阅
def show_score(request, _id):
    totle = 0
    return HttpResponse(f"客户 {_id} 的总分是 {totle}")

views.py 文件中的内容添加完毕,即可修改 scoring/urls.py 中的 URL 模式字符串了,具体如下:

urlpatterns = [
    path("", views.index, name="index"),
    path("<int:_id>/", views.detail, name="detail"),
    path("<int:_id>/score", views.show_score, name="show_score"),
]

此时还需要关注的一个文件是 settings.py,在该文件中存在一个配置项如下:

ROOT_URLCONF = 'cutegirl.urls'

上述配置项决定了当用户访问的 URL 携带 scoring 时,Django 会自动跳转到 scoring.urls 中进行匹配。

现在可以通过访问下述地址获取不同的展示结果了。

http://127.0.0.1:8000/scoring/2/
http://127.0.0.1:8000/scoring/2/score

代码中 <int:_id> 在后续博客中会补充相应的说明,基本含义是前面是数据类型,后面是视图的参数名。

13.2 重拾模板

scoring 目录下新建一个目录叫做 templates ,然后在 templates 中再创建一个文件夹 ttt,这个文件名可以任意,甚至可以创建多套模板都没有问题。

在编写代码前,先通过命令行向 sqlite 中输入一些数据。

> python manage.py shell
>>> from scoring.models import Customer
>>> cus = Customer(1,"橡皮擦",15012345678)
>>> cus.save()
>>> cus = Customer(2,"1_bit",15066667777)
>>> cus.save()

数据准备完毕,可以通过下述代码输出数据进行基础测试,查看视图与模型之间的关联关系是否打通。
修改 views.py 文件,填入下述内容代码。

from django.http import HttpResponse
from .models import Customer

# 打分系统首页
def index(request):
    customers = Customer.objects.all()
    ret = ",".join([c.name for c in customers])
    return HttpResponse(ret)

此时访问 http://127.0.0.1:8000/scoring/,得到如下内容。

接下来配合视图在对 views.py 中的内容进行修改。

from django.http import HttpResponse
from .models import Customer
from django.template import loader

# 打分系统首页
def index(request):
    customers = Customer.objects.all()
    template = loader.get_template("ttt/index.html")

    context = {
        "customers": customers
    }
    return HttpResponse(template.render(context, request))

上述代码中,优先导入了模型类与 template 中的 loader 模块,然后修改 index 函数,通过 Customer.objects.all() 获取之前录入的客户数据。
template = loader.get_template("ttt/index.html") 用于加载模板,最后将数据通过 context 传递到 index.html 页面中。

此时修改一下 index.html 页面逻辑,内容如下:

{% if customers %}
<ul>
  {% for c in customers %}
  <li><a href="/scoring/{{ c._id }}">{{ c.name }}</a></li>
  {% endfor %}
</ul>
{% else %}
<p>无客户</p>
{% endif %}

刷新页面,出现如下 BUG,原因是 c._id 导致,因 _ 开头的变量在模板中被当做私有变量。

TemplateSyntaxError at /scoring/ Variables and attributes may not begin with
underscores: 'c._id'

解决办法涉及新的模板标签知识点。
scoring 目录中新建立一个 templatetags 文件夹,其中创建两个文件 __init__.pygetid.py,目录结构如下:

__init__.py 保持为空即可,getid.py 中增加如下代码。这里相当于在 Django 模板中手动创建了一个过滤器。顺便再回顾一下 Django 模板语法。

  • 变量:两个大括号括起来的 {{变量名}}
  • 标签:代码段 {% 代码块 %}
  • 过滤器:竖线(|);
  • 注释:{# 这里是注释 #}
from django import template
register = template.Library()

@register.filter(name='getid')
def getid(d):
    return d._id

完成准备工作之后,修改 index.html 文件。

{% load getid %} {% if customers %}
<ul>
  {% for c in customers %}
  <li><a href="/scoring/{{ c|getid }}">{{ c.name }}</a></li>
  {% endfor %}
</ul>
{% else %}
<p>无客户</p>
{% endif %}

再次运行代码,得到的页面源码如下:

<ul>
  <li><a href="/scoring/1">橡皮擦</a></li>
  <li><a href="/scoring/2">1_bit</a></li>
</ul>

views.py 代码中的函数会返回一个 HttpResponse 对象到浏览器,该处理逻辑经常使用,所以 Django 提供了一个内置好的简写函数,render

from django.shortcuts import render
# 打分系统首页
def index(request):
    customers = Customer.objects.all()
    context = {
        "customers": customers
    }
    return render(request, "ttt/index.html", context)

刚才已经提及了 Django 模板系统中的常见语法,对于模板系统还有如下内容需要补充。

修改模板中的超链接生成方式,在前文中使用字符串拼接的方式 <a href="/scoring/{{ c|getid }}">{{ c.name }}</a> 生成了一个超链接,该内容可以进行优化,在 scoring/urls.py 中,我们给每个 URL 模式都进行了命名。

urlpatterns = [
    path("", views.index, name="index"),
    path("<int:id>/", views.detail, name="detail"),
    path("<int:id>/score", views.show_score, name="show_score"),
]

通过上述命名,可以修改模板中超链接的生成方式为:

{% for c in customers %}
<li><a href="{% url 'detail' c|getid%}">{{ c.name }}</a></li>
{% endfor %}

在 Django 中任何功能都是以应用形式存在的,即会出现多个应用在一个项目内的场景,此时 URL 模式可能会出现相同内容。解决办法非常简单,通过在 urls.py 文件中增加 app_name 变量设置 URLconf 的命名空间。

from django.urls import path
from . import views

app_name = "scoring"
urlpatterns = [
    path("", views.index, name="index"),
    path("<int:id>/", views.detail, name="detail"),
    path("<int:id>/score", views.show_score, name="show_score"),
]

命名名称空间之后,就可以在 index.html 文件中增加名称空间相关数据。

{% for c in customers %}
<li><a href="{% url 'scoring:detail' c|getid%}">{{ c.name }}</a></li>
{% endfor %}

13.3 本篇博客小节

本篇我们再次对打分系统中的视图与模板进行了补充与学习,一起打卡吧。


今天是持续写作的第 131 / 200 天。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。