Django学习2-URL模式,模板基本语法

创建网页

使用Django创建网页的过程通常分三个步骤:定义URL、编写视图函数和编写模板。
每个URL都被映射到特定的视图-视图函数获取处理网页信息的数据。视图通常需要一个模板,后者生成浏览器能理解的网页。

映射URL

通过浏览器中输入URL以及单机链接来请求网页,在URL配置文件urls.py中设置处理主页(http://localhost:8000)的视图函数。

"""
from django.contrib import admin
from django.urls import path
from learning_logs import views as learn_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', learn_view.index)
]

视图函数

在应用learning_log的view.py中编写视图函数:

from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
    html = '<html><head><title>Index</title></head>' \
           '<body><h1>Welcome to Ulysses</h1>' \
           '</body>' \
           '</html>'
    return HttpResponse(html)

运行项目,访问主页得到的结果
在这里插入图片描述
接下来试着为Topic和Post创建相关链接

创建其他网页

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', learn_view.index),
    path('topic/<int:topic_id>/', learn_view.topic, name='topic'),
    path('post/<int:post_id>/', learn_view.post, name='post'),
]

可以在URL地址指定捕获的值的类型,如<int:id>,指定将url中的’id’转为int型(默认字符串);name参数相当于是给网址添加了一个名称,可以通过这个name,可以在view,models, templates获取网址。只要这个名字不变,在setting.py中修改了url后,也能通过这个名字获取修改后的网址。
通过reverse(name,args=(,))获取URL。

>>> from django.urls import reverse
>>> reverse('topic',args=(1,))
'/topic/1/'
>>> reverse('post',args=(1001,))
'/post/1001/'
>>> 

topic和post视图函数:当访问 ‘http://127.0.0.1:8000/topic/1/’ 时,获取topic_id,在数据库中查询获取对于的topic,将id和text存储在要发送给模板的上下文context中。render接受上下文并讲其赋值给appname/templates下指定的网页,返回一个HttpResponse。当id对应的post或topic不存在时, QuerySet生成DoesNotExist错误。

def topic(request, topic_id):
    """根据id访问topic的信息"""
    try:
        t = Topic.objects.get(id=topic_id)
        text = t.text
        context = {'id':topic_id, 'text':text}
        return render(request, 'topic.html', context)
    except Topic.DoesNotExist:
        return HttpResponseNotFound(f'<h1>Topic:{topic_id} not exist</h1>')

def post(request, post_id):
    """根据id访问post信息"""
    try:
        t = Post.objects.get(id=post_id)
        text = t.text
        context = {'id': post_id, 'text': text}
    except Post.DoesNotExist:
        raise Http404(f'Post:{post_id} not exist')
    return render(request, 'post.html', context)

使用HttpResponseNotFound 来定义错误界面,Web最常见的错误类型就是404错误。手动抛出Http404错误,Django会捕获这个错误并返回一个标准的404错误界面和404错误码。
Django的404错误界面
在这里插入图片描述
POST界面
在这里插入图片描述

模板

模板是包含响应文本的文件,其中包含占位变量表示的动态部分,其具体值只在请求的上下文才知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染

基本语法

  1. 控制结构{% %}
  2. 变量 {{ }}
  3. 注释{# #}
    例如:
{#  Django #}
{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
  <a href="{{ story.get_absolute_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

变量

在模板中的{{ i }}结构表示变量,这是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据结构中获取。Django支持python中所有的Python数据类型比如列表、字段、对象等

<p>this is a dicectory:{{ mydict['key'] }} </p>
<p>this is a list:{{ mylist[3] }} </p>
<p>this is a object:{{ myobject.something() }} </p>
{% for k, v in defaultdict.items %}
    Do something with k and v here...
{% endfor %}

变量过滤器

变量的值可以使用过滤器修改。过滤器在添加变量名后,二者以竖线分隔。如:

<p>Hello, {{ user|capitalize }}!</p>

有些过滤器带有参数: {{ bio|truncatewords:30 }}:会显示bio的前30个单词。当参数中有空格时必须带引号,如 {{ list|join:", " }}

过滤器名说明example
add加法运算,给变量加一个值,当两个变量都为列表时,相当于extend{{ value|add:"2" }}
{{ first|add:second }}
addslashes给引号前加斜杠: "I\'m using Django"{{ value|addslashes }}
capfirst首字母大写:django-> Django{{ value|capfirst }}
center指定变量居中:" Django ""{{ value|center:"15" }}"
cut除去变量中的指定值 “String with spaces” -> “Stringwithspaces”{{ value|cut:" " }}
date指定日期时间的输出格式{{ value|date:"D d M Y" }}
default变量的值为False或为空指定一个默认值{{ value|default:"nothing" }}
default_if_none变量值为且仅为None时,指定默认值{{ value|default_if_none:"nothing" }}
dictsort根据给定的键对字典进行排序,也可对序列的列表进行排序{{ value|dictsort:"name" }}
{{ value|dictsort:0 }}
dictsortreversed排序,与dictsort相反
divisibleby是否内被整除,返回True,False{{ value|divisibleby:"3" }}
escape转义HTML字符串< 变为&lt;{% autoescape off %}
{{ title|escape }}
{% endautoescape %}
escapejs转义javascript字符{{ value|escapejs }}
filesizeformat将值的大小,格式化为易读的形式’13 KB’, ‘4.1 MB’, ‘102 bytes’, etc{{ value|filesizeformat }}
first返回列表的首个元素{{ value|first }}
floatformat省略小数位,默认舍入到一个小数位{{ value|floatformat : 3}}
force_escape转义多个HTML字符串{% autoescape off %}
{{body|linebreaks|force_escape }}
{% endautoescape %}
get_digit获取指定位置数值,从右数起{{ value|get_digit:"2" }}
iriencode转义iri字符{{ value|iriencode }}
join给序列增加一个字符串,像python的str.join(list){{ value|join:" // " }}
json_script将Python数据以JSON形式输出{{ value|json_script:"hello-data" }}
last输出序列的最后一个元素{{ value|last }}
length变量的长度{{ value|length }}
length_is变量长度是否为指定值{{ value|length_is:"4" }}
linebreaks使用HTML的换行符单换行:<br>,换行空行<p>{{ value|linebreaks }}
linebreaksbr使用<br>换行{{ value|linebreaksbr }}
linenumber显示行号{{ value|linenumbers }}
ljust左对齐"{{ value|ljust:"10" }}"
lower全部变为小写{{ value|lower }}
make_list将变量拆分成列表形式{{ value|make_list }}
phone2numeric将电话号码(可能包含字母)转换为其等效数字{{ value|phone2numeric }}
pluralize返回复数后缀,默认’s’{{ num_messages|pluralize }}
pprint包装了pprint.pprint()的装饰器
random返回变量列表的随机元素{{ value|random }}
rjust右对齐"{{ value|rjust:"10" }}"
safe将字符串标记为在输出之前不需要进一步的HTML转义。当autoescaping关闭时,此过滤器无效{{ var|safe|escape }}
safeseq将安全过滤器应用于序列的每个元素。 与在序列上运行的其他过滤器结合使用,例如join{{ some_list|safeseq|join:", " }}
slice返回切片{{ some_list|slice:":2" }}
slugify转换为ASCII码,将空格转换为连字符。 删除不是字母数字,下划线或连字符的字符。 转换为小写。 还剥去前导和尾随空格。{{ value|slugify }}
stringformat根据参数格式化变量,10->1.000000E+01{{ value|stringformat:"E" }}
striptags去除[X]HTML标记{{ value|striptags }}
time格式化时间格式{{ value|time:"H:i" }}
timesince自给定时间后过去了的间隔(e.g., “4 days, 6 hours”){{ blog_date|timesince:comment_date }}
timeuntil距给定时间还有…{{ conference_date|timeuntil:from_date }}
title将字符转为标题形式{{ value|title }}
truncatechars如果字符串长于指定的字符数,则截断该字符串{{ value|truncatechars:9 }}
truncatechars_html截短HTML标签内字符{{ value
truncatewords根据指定数值截断单词{{ value|truncatewords:2 }}
truncatewords_html截短HTML标签内的单词{{ value|truncatewords_html:2 }}
unordered_list递归地获取自嵌套列表并返回HTML无序列表 - 没有打开和关闭<ul>标记。{{ var|unordered_list }}
upper大写{{ value|upper }}
urlencode转义变量中的url的{{ value|urlencode }}
urlize将url和email地址转换为可点击的形式{{ value|urlize }}
urlizetrunc将url和email地址转换为可点击的形式,限制长度{{ value|urlizetrunc:15 }}
wordcount单词数统计{{ value|wordcount }}
wordwrap根据给的行长度包装{{ value|wordwrap:5 }}
yesno映射True, False, None{{ value|yesno:"yeah,no,maybe" }}
  • 默认自动转义:{'name':'<b>Hello</b>'}结果为<b>Hello</b>
  • 关闭autoescape:{'name':'<b>Hello</b>'}结果为Hello
  • safe不转义:{'name':'<b>Hello</b>'}结果为Hello

默认情况下出于安全考虑会转义所有变量。当一个变量为<b>Hello</b>没有添加safe过滤器时,显示的结果为
在这里插入图片描述
浏览器能显示<b>元素,但不会解释它。
当添加safe过滤器时,结果为
在这里插入图片描述
当需要显示变量中存储的HTML代码时,可使用safe过滤器。

控制结构

条件判断语句与Python类似,但其不需要使用冒号结尾,而结束控制语句,需要使用endif关键字:

{% if daxin.safe %}
	daxin is safe.
{% elif daxin.dead %}
	daxin is dead
{% else %}
	daxin is okay
{% endif %}

for循环实现一组元素的渲染:

<ul>
{% for user in users %}
	<li>{{ user.username|title }}</li>
{% endfor %}
</ul>

模板继承

模板继承类似于python代码的类继承。首先创建名为base.html的基模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href={{ static('css/mystyle.css') }}>
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

基模板中定义的区块可在衍生模板中覆盖。使用blockendblock指令在基模板中定义内容区块。在上述基模板中定义了head、title、content和footer区块。
新建一个topics.html的文件,继承基模板,用来显示全部的topics。

{% extends "base.html" %}

{% block title %}Topics{% endblock %}
{% block head %}
    {{ block.super }}

{% endblock %}
{% block content %}
{% for topic in topics %}
    <h2>{{ topic.id }}</h2>
    <p>{{ topic.text }}</p>
{% endfor %}
{% endblock %}

extends指令声名这个模板衍生自base.html。在extends指令后,基模板的4个区块被重新定义,模板引擎将其插入合适的位置。如果基模板和衍生模板的同名区块有内容,衍生模板的内容会被显示。在衍生模板区块中调用block.super,引用基模板的同名内容。topics.html里的head区块引用了基模板的css文件。

css等静态文件的使用

在应用目录下创建static文件夹,存放css、图片等静态文件: 在这里插入图片描述
指定css文件路径

	{# jinja2 #}
    {% block head %}
    <link rel="stylesheet" href={{ static('css/mystyle.css') }}>
	
	{# django #}
	{% load static %}
	<link rel="stylesheet" href={{ static('css/mystyle.css') }}>
	
	<img src="{% static 'img/nan.jpg' %}" alt="南风不竞"/>

使用模板创建topics和posts

视图函数:

def topics(request):
    """全部的topics"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request, 'topics.html', context)

def posts(request):
    """全部的posts"""
    posts = Post.objects.order_by('date_added')
    context = {'posts':posts}
    return render(request, 'posts.html', context)

根据添加时间排序,显示全部的内容。
映射url:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', learn_view.index),
    path('topic/<int:topic_id>/', learn_view.topic, name='topic'),
    path('topics/', learn_view.topics, name='topics'),
    path('post/<int:post_id>/', learn_view.post, name='post'),
    path('posts/', learn_view.posts, name='posts')
]

显示的网页:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值