Django基本平台搭建

开发环境

安装最新版的Django版本

Django实际是一个平台搭建工作,内含一些命令,能够快速的完成平台搭建

  1. 安装最新版本的Django

$ pip install django

  1. django-admin.py添加到我们的环境变量
    方便之后通过Django的命令直接操作

项目创建

1.项目创建
到项目指定目录下

$django-admin.py startproject my_blog

  1. 建立Django app
    到项目指定目录下

$python manage.py startapp article

  1. 添加APP
    在my_blog/my_blog/settings.py(注意:应该是项目根目录底下的配置文件)
INSTALLED_APPS = (
    ...
    'article',  #这里填写的是app的名称
)
  1. 运行程序
    到项目指定目录下

$python manage.py runserver localhost:9000

  1. 命令总结

python manage.py <command> [options] #Django Command
python manange.py -h帮助文档
django-admin.py startproject my_blog #创建项目
python manage.py startapp article #创建app
python manage.py runserver localhost:9000 #启动Django中的开发服务器

项目设置

数据库设置

  1. Django Model
  • 每一个Django Model都继承自django.db.models.Model
  • 在Model当中每一个属性attribute都代表一个database field
  • 通过Django Model API可以执行数据库的增删改查, 而不需要写一些数据库的查询语句
  1. 设置数据库
    Django项目建成后, 默认设置了使用SQLite数据库, 在 my_blog/my_blog/settings.py 中可以查看和修改数据库设置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
  1. 创建models
    在my_blog/article/models.py下编写如下程序:
from django.db import models

# Create your models here.
class Article(models.Model) :
    title = models.CharField(max_length = 100)  #博客题目
    category = models.CharField(max_length = 50, blank = True)  #博客标签
    date_time = models.DateTimeField(auto_now_add = True)  #博客日期
    content = models.TextField(blank = True, null = True)  #博客文章正文

    #python2使用__unicode__, python3使用__str__
    def __str__(self) :
        return self.title

    class Meta:  #按时间下降排序
        ordering = ['-date_time']
  1. 同步数据库

$ python manage.py migrate #命令行运行该命令
$ python manage.py makemigrations

  1. Django Shell

$ python manage.py shell

Admin

Django有一个优秀的特性, 内置了Django admin后台管理界面, 方便管理者进行添加和删除网站的内容.

  1. 设置Admin
    可以在my_blog/my_blog/settings.py中查看
    同时也已经添加了进入后台管理的url, 可以在my_blog/my_blog/urls.py中查看
  2. 创建超级用户

$ python manage.py createsuperuser

现在可以在浏览器中输入localhost:9000/admin输入账户和密码进入后台管理

Views和URL

  1. 网页程序的逻辑
    request进来->从服务器获取数据->处理数据->把网页呈现出来
  • url设置相当于客户端向服务器发出request请求的入口, 并用来指明要调用的程序逻辑
  • views用来处理程序逻辑, 然后呈现到template(一般为GET方法, POST方法略有不同)
  • template一般为html+CSS的形式, 主要是呈现给用户的表现形式
  1. 简单Django Views和URL
    Django中views里面的代码就是一个一个函数逻辑, 处理客户端(浏览器)发送的HTTPRequest, 然后返回HTTPResponse,那么开始在my_blog/article/views.py中编写简单的逻辑
#现在你的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设置

from django.conf.urls import url
from django.contrib import admin
from article import views
urlpatterns = [

    url(r'^admin/', admin.site.urls),
    url(r'^$', views.home),
    ]

url()函数有四个参数, 两个是必须的:regex和view, 两个可选的:kwargs和name

  • regex是regular expression的简写,这是字符串中的模式匹配的一种语法, Django 将请求的URL从上至下依次匹配列表中的正则表达式,直到匹配到一个为止。
  • View当 Django匹配了一个正则表达式就会调用指定的view逻辑, 上面代码中会调用article/views.py中的home函数
  • kwargs任意关键字参数可传一个字典至目标view
  • name命名你的 URL, 使url在 Django 的其他地方使用, 特别是在模板中

Django Views和URL更近一步

现在我们这样做, 在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

from django.conf.urls import url
from django.contrib import admin
from article import views
urlpatterns = [

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

^(?P<my_args>\d+)/$这个正则表达式的意思是将传入的一位或者多位数字作为参数传递到views中的detail作为参数, 其中?P<my_args>定义名称用于标识匹配的内容

访问http://localhost:9000/1000/

Template使用

my_blog(项目根目录)下添加文件名, 文件夹名为templates

在my_blog/my_blog/settings.py下设置templates的位置

TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates')
TEMPLATES = (
    ...
    DIRS: [TEMPLATE_PATH],
)
  • 第一个template
    templates/test.html 简单第一个 template html文件
    注意:要添加<meta charset="utf-8">,否则会出现编码错误
<!--在test.html文件下添加-->
<!DOCTYPE html>
<meta charset="utf-8">
<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/views.py中添加一个函数逻辑

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

然后设置对应的url在my_blog/my_blog/urls.py下

 url(r'^test/$', views.test),

render()函数中第一个参数是request 对象, 第二个参数是一个模板名称,第三个是一个字典类型的可选参数. 它将返回一个包含有给定模板根据给定的上下文渲染结果的 HttpResponse对象。

  • 正式编写template
    在template文件夹下增加base.html
<!doctype html>
<meta charset="utf-8">
<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://labfile.oss.aliyuncs.com/courses/487/pure-min.css">
    <link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/grids-responsive-min.css">
    <link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/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">Andrew Liu Blog</h1>
            <h2 class="brand-tagline">Snow Memory</h2>
            <nav class="nav">
                <ul class="nav-list">
                    <li class="nav-item">
                        <a class="pure-button" href="https://github.com/Andrew-liu">Github</a>
                    </li>
                    <li class="nav-item">
                        <a class="pure-button" href="http://weibo.com/dinosaurliu">Weibo</a>
                    </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://andrewliu.tk/about/">About Me</a></li>
                        <li><a href="http://twitter.com/yuilibrary/">Twitter</a></li>
                        <li><a href="http://github.com/yahoo/pure/">GitHub</a></li>
                    </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/views.py, 并删除test.html

def home(request):
    post_list = Article.objects.all()  #获取全部的Article对象
    return render(request, 'home.html', {'post_list' : post_list})

修改my_blog/my_blog/urls.py

注意:会出现no such table的问题,解决办法:

  • 运行’manage.py makemigrations’, 这样可以’make new migrations’
  • 然后运行’manage.py migrate’, 接着’apply them’

动态URL

目前只有一个主页的空盒子, 而大部分时候我们希望能够让每篇博客文章都有一个独立的页面,Django给我们提供了一个方便的解决方法, 就是动态URL

  • 修改my_blog/article/views.py代码:
# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import HttpResponse
from article.models import Article
from datetime import datetime
from django.http import Http404

# Create your views here.
def home(request):
    post_list = Article.objects.all()  #获取全部的Article对象
    return render(request, 'home.html', {'post_list' : post_list})

def detail(request, id):
    try:
        post = Article.objects.get(id=str(id))
    except Article.DoesNotExist:
        raise Http404
    return render(request, 'post.html', {'post' : post})

id是每个博文的唯一标识, 所以这里使用id对数据库中的博文进行查找

  • my_blog/my_blog/urls.py中修改url设置:
from django.conf.urls import url
from django.contrib import admin
from article import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.home, name = 'home'),
    url(r'^(?P<id>\d+)/$', views.detail, name='detail'),
]
  • 在templates下建立一个用于显示单页博文的界面 post.html
#post.html
{% extends "base.html" %}

{% block content %}
<div class="posts">
        <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|date:"Y /m /d"}}</a> <a class="post-category post-category-js" href="#">{{ post.category }}</a>
                    </p>
            </header>

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

可以发现只需要对home.html进行简单的修改, 去掉循环就可以了.

  • 修改home.html和base.html, 加入动态链接和主页, 归档, 专题和About Me按钮
<!--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"><a href="{% url "detail" id=post.id %}">{{ post.title }}</a></h2>

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

                <div class="post-description">
                    <p>
                        {{ post.content }}
                    </p>
                </div>
                <a class="pure-button" href="{% url "detail" id=post.id %}">Read More >>> </a>
        </section>
    {% endfor %}
</div><!-- /.blog-post -->
{% endblock %}
  • base.html:
<!--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://labfile.oss.aliyuncs.com/courses/487/pure-min.css">
    <link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/grids-responsive-min.css">
    <link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/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"><a href="{% url "home" %}">Andrew Liu Blog</a></h1>
            <h2 class="brand-tagline">Snow Memory</h2>
            <nav class="nav">
                <ul class="nav-list">
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">Archive</a>
                    </li>
                    <li class="nav-item">
                        <a class="pure-button" href="https://github.com/Andrew-liu/my_blog_tutorial">Github</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-error pure-button" href="http://weibo.com/dinosaurliu">Weibo</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">Pages</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">About Me</a>
                    </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://andrewliu.tk/about/">About Me</a></li>
                        <li><a href="http://twitter.com/yuilibrary/">Twitter</a></li>
                        <li><a href="http://github.com/yahoo/pure/">GitHub</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容