1. 程式人生 > >Django搭建簡易部落格教程(二)

Django搭建簡易部落格教程(二)

十一、View和URL

網頁程式的邏輯:request進來 -> 從伺服器獲取資料 -> 處理資料 -> 把網頁呈現出來

url 設定相當於客戶端向伺服器發出request請求的入口,並用來指明要呼叫的程式邏輯

views 用來處理程式邏輯,然後呈現到template(一般為GET方法,POST方法略有不同)

template 一般為html+CSS的形式,主要是呈現給使用者的表現形式

Django中views裡面的程式碼時一個一個函式邏輯,處理客戶端(瀏覽器)傳送的HTTPRequest,然後返回HTTPResponse。

那麼開始在my_blog/article/views.py中編寫簡單的邏輯

from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def home(request):
    return HttpResponse("Hello World, Django")

如何使這個邏輯在http請求進入時被呼叫,這裡需要在my_blog/my_blog/urls.py中進行url設定

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.contrib import admin

urlpatterns = [
    # url(r'^$', 'article.views.home'),
    # url(r'^(?P<my_args>\d+)/$', 'article.views.detail', name='detail'),
    url(r'^admin/', admin.site.urls),
    url(r'^$', 'article.views.home'),
]


url() 函式有四個引數,兩個是必須的:regex和views,兩個可選的:kwargs和name

regex是regular expression的簡寫,這是字串中的模式匹配的一種語法,Django將請求的URL從上至下依次匹配列表中的正則表示式,直到匹配到一個為止。

view當Django匹配了一個正則表示式就會呼叫指定的view邏輯,上面程式碼中會呼叫article/views.py中的home函式

kwargs任意關鍵字引數可傳一個字典至目標view

name命名你的URL,使url在Django的其他地方使用,特別是在模組中

很多時候我們希望給view中的函式邏輯傳入引數,從而呈現我們想要的結果

現在再my_blog/article/views.py 加入如下程式碼:

def detail(request, my_args):
	return HttpResponse("You're looking at my_args %s." % my_args)

在my_blog/my_blog/urls.py 中設定對應的url

urlpatterns = [
    # url(r'^$', 'article.views.home'),
    # url(r'^(?P<my_args>\d+)/$', 'article.views.detail', name='detail'),
    url(r'^admin/', admin.site.urls),
    url(r'^$', 'article.views.home'),
    url(r'^(?P<my_args>\d+)/$', 'article.views.detail', name='detail'),
]
^(?P<my_args>\d+)/$這個正則表示式的意思是將傳入的一位或者多位數字作為引數傳遞到views中的detail作為引數, 其中?P<my_args>定義名稱用於標識匹配的內容

輸入以下url:

http://localhost:8000/1000/


嘗試傳參訪問資料庫

修改my_blog/article/views.py中的程式碼:

from django.shortcuts import render
from django.http import HttpResponse
from article.models import Article
# Create your views here.
def home(request):
    return HttpResponse("Hello World, Django")

def detail(request, my_args):
    post = Article.objects.all()[int(my_args)]
    str = ("title = %s, category = %s, date_time = %s, content = %s" 
        % (post.title, post.category, post.date_time, post.content))
    return HttpResponse(str)
訪問 http://localhost:8000/1/

1表示訪問資料庫的article表中的第一行資料



十二、第一個Template

到目前為止還沒有寫前端,只是簡單的把後端資料顯示到頁面上,沒有涉及HTML程式碼。

目前流行的前端工具有Bootstrap和Pure,本文中使用更輕量級的Pure

在app的資料夾article下建立templates資料夾

檔案構成如下:

my_blog
├── article
│   ├── __init__.py
│   ├── templates
│   ├── admin.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-34.pyc
│   │       └── __init__.cpython-34.pyc
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── my_blog
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-34.pyc
    │   ├── settings.cpython-34.pyc
    │   ├── urls.cpython-34.pyc
    │   └── wsgi.cpython-34.pyc
    ├── settings.py
    ├── urls.py
    └── wsgi.py


把template建立在app的檔案目錄下就不需要設定templates的位置路徑了

在templates資料夾中建立一個html檔案, templates/test.html

<!--在test.html資料夾下新增-->
<!DOCTYPE html>
<html>
    <head>
        <title>Just test template</title>
        <style>
            body {
               background-color: red;
            }
            em {
                color: LightSeaGreen;
            }
        </style>
    </head>
    <body>
        <h1>Hello World!</h1>
        <strong>{{ current_time }}</strong>
    </body>
</html>

其中{{ current_time }}是Django Template中變數的表示方式

在article/view.py中新增一個函式邏輯

from django.shortcuts import render
from django.http import HttpResponse
from article.models import Article
from datetime import datetime
# Create your views here.
def home(request):
    return HttpResponse("Hello World, Django")


def detail(request, my_args):
    post = Article.objects.all()[int(my_args)]
    str = ("title = %s, category = %s, date_time = %s, content = %s" 
        % (post.title, post.category, post.date_time, post.content))
    return HttpResponse(str)


def test(request) :
    return render(request, 'test.html', {'current_time': datetime.now()})


render()函式中第一個引數是request 物件, 第二個引數是一個模板名稱,第三個是一個字典型別的可選引數. 它將返回一個包含有給定模板根據給定的上下文渲染結果的 HttpResponse物件。

然後設定對應的url在my_blog/urls.py下

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^(?P<my_args>\d+)/$', 'article.views.detail', name='detail'),
    url(r'^test/$', 'article.views.test'),
]



十三、使用Pure編寫template

在templates資料夾下增加base.html,程式碼如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A layout example that shows off a blog page with a list of posts.">

    <title>Andrew Liu Blog</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css">
    <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/grids-responsive-min.css">
    <link rel="stylesheet" href="http://picturebag.qiniudn.com/blog.css">
</head>
<body>
<div id="layout" class="pure-g">
    <div class="sidebar pure-u-1 pure-u-md-1-4">
        <div class="header">
            <h1 class="brand-title">Xiaoquantou Blog</h1>
            <h2 class="brand-tagline">小拳頭 - Hello World</h2>
            <nav class="nav">
                <ul class="nav-list">
                    <li class="nav-item">
                        <a class="pure-button" href="http://blog.csdn.net/xiaoquantouer">Github</a>
                    </li>
                    <li class="nav-item">
                        <a class="pure-button" href="http://blog.csdn.net/xiaoquantouer">Weibo</a></span>
                    </li>
                </ul>
            </nav>
        </div>
    </div>

    <div class="content pure-u-1 pure-u-md-3-4">
        <div>
            {% block content %}
            {% endblock %}
            <div class="footer">
                <div class="pure-menu pure-menu-horizontal pure-menu-open">
                    <ul>
                        <li><a href="http://blog.csdn.net/xiaoquantouer">About Me</a></li></span>
                        <li><a href="http://blog.csdn.net/xiaoquantouer">Twitter</a></li></span>
                        <li><a href="http://blog.csdn.net/xiaoquantouer">GitHub</a></li></span>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

上面這段html編寫的頁面是一個模板, 其中{% block content %} {% endblock %}欄位用來被其他繼承這個基類模板進行重寫

繼續在templates資料夾下新增home.html檔案

{% extends "base.html" %}

{% block content %}
<div class="posts">
    {% for post in post_list %}
        <section class="post">
            <header class="post-header">
                <h2 class="post-title">{{ post.title }}</h2>

                    <p class="post-meta">
                        Time:  <a class="post-author" href="#">{{ post.date_time }}</a> <a class="post-category post-category-js" href="#">{{ post.category }}</a>
                    </p>
            </header>

                <div class="post-description">
                    <p>
                        {{ post.content }}
                    </p>
                </div>
        </section>
    {% endfor %}
</div><!-- /.blog-post -->
{% endblock %}

其中
- {% for <element> in <list> %}與{% endfor %}成對存在, 這是template中提供的for迴圈tag
- {% if <elemtnt> %} {% else %} {% endif %}是template中提供的if語句tag
- template中還提供了一些過濾器

然後修改my_blog/article/view.py,並刪除test.html