1. 程式人生 > >模板、過濾器、模板繼承以及思路

模板、過濾器、模板繼承以及思路

建立模板

1、新建一個templates資料夾 --- 用來存放html

2、在站點中的settings的TEMPLATES中進行以下設定指定templates目錄地址,

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 設定templates的路徑
        'DIRS': [os.path.join(BASE_DIR,'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

3、在templates下建立html檔案

4、使用:在應用的views中設定函式,將html檔案渲染到頁面,將想要顯示的物件也引入

在views中方法返回/頁面
data = {
    'stus':stus
}
render(request,'壓面',data)

def index(request):
    if request.method == 'GET':
        stus = Student.objects.all()
        return render(request,'index.html',{'stus':stus})

5、在html中進行編輯

在html中使用for、if、while等需要注意格式問題,使用完函式需要加{% end函式名 %}
例子:
{% for stu in stus %}
    ID:{{ stu.id }}
    年齡:{{ stu.s_sge }}
{% endfor %}

{% if 表示式 %}
語句1
{% else %}
語句2
{% endif %}
例子
{% if stu.s_sex %}
    性別:男
{% else %}
    性別:女
{% endif %}

頁面放在templates資料夾中,靜態的檔案(css、js等)放在static中

for迴圈,
if 
ifequal --- 如果相等
forloop.counter --- 迴圈計數,從1開始依次加1
forloop.counter0 --- 迴圈計數,從0開始
forloop.revcounter0 --- 迴圈計數,倒序到0
forloop.frist --- 如果是第一個則是Ture
forloop.last --- 如果是最後一個則是Falase
{% for xx in xxx %}

{% endfor %}

{% if xxx==1 %}

{% endif %}

if的另一個寫法

{% ifequal forloop.counter0 1 %}
    <span style="font-weight:bold;">年齡:{{stu.s_age }}</span>
{% else %}
    <span>年齡:{{ stu.s_age }}</span>
{% endifequal %}

編號

{{ forloop.counter }} ---迴圈一次值加一,預設是1,counter0為從0開始 revcounter -- 倒序
<!-- forloop迴圈呼叫  counter計數器-->
編號: {{ forloop.counter0 }}
{% if forloop.counter0 == 1 %}
    <span style="color:red"> 學生:{{ stu.s_name}}</span>
{% else %}
    <span style="color:yellow"> 學生:{{ stu.s_name}}</span>
{% endif %}

static資料夾(css、js、和images)

1、建立一個static資料夾,因為站點中的settings.py有:
STATIC_URL = '/static/'---如果檔名為其他名字,這裡相應的進行修改就行了
在html檔案中可以通過{% load static from staticfiles %}進行使用路徑,例如:
    <img src="{% static 'myApp/img/2.png' %}"/> --- 這裡的static就是STATIC_URL的static,運用它可以方便路徑發生改變時進行修改
2、設定static的路徑
STATIC_URL = '/static/' --- 普通檔案路徑(例如圖片),如果只是圖片路徑可以不寫下面的程式碼

STATICFILES_DIRS = [   ---  CSS和JS等需要使用此路徑
    os.path.join(BASE_DIR, 'static')

]


靜態css、js、imgage樣式的引入

在html中引入css、js、images
第一種:
<link rel="stylesheet" href="/static/css/index.css" >

第二種:
<!-- load裝載 -->
{% load static  %}
<link href="{% static 'css/index.css' %}" rel="stylesheet">
最好使用第二種

js和imgage的引入也是一樣

註釋

<!-- 不能寫成大括號中包含兩個百分號的格式,會註解-->
<!-- {% %} -->
 
<!-- 單行註釋 --> ---- 這個註釋會在後臺程式碼中顯示
    {# 註釋 #} --- 不會再後臺中顯示
<!-- 多行註釋 -->
{% comment %}

{% endcomment%}

請求

request

http:get請求
    request.GET.get()
    
http:post請求
    request.POST.get()

判斷請求:    
request.method ==> GET,POST

render方法解釋

此方法的作用---結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 物件。

解析

def index(request):
    if request.method == 'GET':
        stus = Student.objects.all()
        # 其中{'stus':stus}的values的值是學生所有的物件,鍵就是在頁面解析的引數的值
        return render(request,'index.html',{'stus':stus})
        
在html頁面通過{{ stus }} --- 將引數進行解析,獲得Queryset物件
例子:
    for迴圈用於解析資料,在頁面中進行展示
    {% for stu in stus %}
        姓名:{{ stu.s_name }}
        年齡:{{ stu.s_age }}
        {% if stu.s_sex %}
            性別:男
        {% else %}
            性別:女
        {% endif %}
        <br/>
    {% endfor %}
在頁面顯示學生物件的姓名和年齡

注意all()的使用

在html中獲得Queryset不在是all(),而是all
{% for course in stu.course_set.all %}
    課程:{{ course.c_name }}
{% endfor %}

過濾器

格式:{{ 物件.欄位 | 過濾器:值 }}
add:數值
add:10 --- 加10     add:-10 --- 減10
語文成績:{{stu.language_score | add:10 }}

date:'y-m-d h-m-s'--- 時間轉換,如果時間是英文顯示的,可以加過濾器date變為中文顯示
建立時間:{{stu.create_time | date:'y-m-d h:m:s'}}

upper --- 大寫  lower --- 小寫
姓名:{{stu.s_name | upper | lower}} --- 多個過濾器可以一起寫,採用最後一個過濾器

為了安全起見和防止頁面是亂碼,django提供了safe 過濾器,主要是一些特殊字元、空格、換行等
為了想要在頁面顯示正常,需要在資料後新增safe過濾器

將帶樣式的字串渲染:{{ context | safe}} 
切片:
    列表:{{ lsit|slice:'2' }} --- 結果是列表下標為0和1元素組成的列表
    字串:{{ string|slice:':2' }} --- 擷取字串'st'

顯示關聯表的資訊

<!-- 根據學生找到班級名稱 -->
    班級:{{stu.g.g_name}}  --- g是在學生中關聯的外來鍵關係名
<!-- 找到學生的課程 -->
    {% for course in stu.course_set.all %}
        課程:{{ course.c_name }}
    {% endfor %}

思路

1、先確定要完成的功能,在urls中定義路由
     # 返回頁面,學生資訊
     url(r'selStuen',views.selStuen,name='sel_stu'),
2、在views中建立方法
    def selStuen(request):
    if request.method == 'GET':
        return render(request, 'students.html')
    返回student.html頁面
3、將要渲染的的物件,包裝進入student.html頁面
    def selStuen(request):
    if request.method == 'GET':
        stus = Student.objects.all()
        return render(request, 'students.html',
                      {'stus': stus})
4、在html中寫迴圈(可以使用表格進行佈局)
    <table align=center>
    <tr >
        <th >ID</th>
        <th>姓名</th>
        <th>年齡</th>
        <th>班級</th>
        <th>操作</th>
    </tr>
    {% for stu in stus %}
    <tr>
        <td>{{stu.id}}</td>
        <td>{{stu.s_name}}</td>
        <td>{{stu.s_age}}</td>
        <td>{{stu.g.g_name}}</td>
        <td>
            <a href="">刪除</a>

            <a href="">編輯</a>

            <!--<a href="/app/addStuCourse/{{ stu.id }}">新增課程</a>-->
        </td>
    </tr>
    {% endfor %}
</table>

5、實現刪除功能
    定義路由
    # 刪除
    url(r'deleteStu',views.deleteStu),
    建立方法
    def deleteStu(request):
    if request.method == 'GET':
        stu_id = request.GET.get('stu_id')
        stu = Student.objects.get(id=int(stu_id))
        stu.delete()

        # return HttpResponse('刪除成功')
        # return HttpResponseRedirect('/app/selStuen')
        # 最好用下面的程式碼,不要使用路徑
        return HttpResponseRedirect(reverse('myapp:sel_stu'))
思考:當點選刪除時,我們應該獲得想要刪除的資料的id值

1、在?後傳的值傳進deleteStu中 ---  <a href="/app/deleteStu/?stu_id={{ stu.id }}">刪除</a>
 <a href="{% url 'backweb:index' %}?page={{ i }}">{{ i }}</a> --- 另一種寫法的傳參

?後面的長度:協議並沒有限制長度,但是不同的瀏覽器對齊有不同的限制
後端將接受deleteStu方法

2、<a href="/app/addStuCourse/{{ stu.id }}">新增課程</a> --- 
    設定路由: url(r'addStuCourse/(\d+)', views.addStuCourse) --- (\d+)接收動態的id
    
3、在方法中新增引數,接收穫取的動態id
def addStuCourse(request, id):
    if request.method == 'GET':
        # stu = Student.objects.get(id=id)
        courses = Course.objects.all()
        return render(request, 'courses.html',
                      {'courses': courses})
    if request.method == 'POST':
        stu = Student.objects.get(id=id)
        c_id = request.POST.get('c_id')
        c = Course.objects.get(id=c_id)
        stu.course_set.add(c)
        return HttpResponseRedirect('/app/selStuen/')

注意a標籤的href問題

 <a href="/sunck/quit">退出登陸</a> --- 跳轉到相應的頁面
 
 <a href="sunck/quit">退出登陸</a> --- 在當前的頁面後新增href路徑
  也可以向下面一樣寫:和第一個類似
 <a href="{% url 'backweb:index' %}" class="active">文章列表</a>

模板繼承

挖坑、填坑
一般是建立一個base.html頁面,用來挖坑,建立一個base_main.html用來填頁面共同擁有的坑,在頁面中繼承base_main.html

1、在基礎模板中挖坑(base.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {# 挖坑 #}
        {% block title %}
        {% endblock %}
    </title>
    {# 挖坑 #}
    {% block extCss %} --- 同樣可以給js挖坑
    {% endblock %}
</head>
<body>
    {# 挖坑 #}
    {% block content %}
    {% endblock %}
</body>
</html>

2、填坑 --- 在頁面中繼承繼承模板
{% extends 'base.html' %}

{% block titel %}
    我是首頁
{% endblock %}

{% block extCss %} 
    {{ block.super }} --- 繼承基礎模板坑中的內容,如果不寫繼承就會清空基礎模板的內容
{% endblock %}

{% extends 'base.html' %}可以看做整個base.html頁面,在base.html中挖的坑可以看做是類(base.html)
中的方法,其他頁面通過{% extends 'base.html' %}繼承了base.html的整個頁面

{% 在某個標籤中挖的坑,就可以看做這個標籤中的父坑 %},其他頁面可以通過{{block.super}}繼承這個父坑的
內容,並在其後新增內容(類似於類的繼承)

注意:如果沒有使用{{ blcok.super }}繼承,則父坑的內容將不會繼承

如果不寫坑名則自動繼承主坑的內容

如果寫了坑名,不寫block.super就會清空主坑的內容。

寫了坑名並且使用了block.super就會繼承主坑的內容