本教程根据慕课网<Django入门与实践>编写
基础知识
什么是django?
Django是一个基于Python的高级Web开发框架, 特点:高效,快速,高度集成(不用自己弄底层),免费,开源
上网的流程
输入URL→向目标url发送http请求→服务器把页面响应给浏览器(通过后台编写的代码处理请求)→浏览器解析获取到的页面源代码文档(所以看到的不是html文档)→看到网页
目录结构
- 项目项目目录结构.
├── manage.py与项目进行交互的命令行工具集的入口(项目管理器)
└── myblog项目的一个容器,包含项目最基本的一些配置(不建议修改名称,会影响配置文件)
├── __init__.py声明模块的文件(默认为空,使myblog为一个模块,可以直接在代码中引用)
├── settings.py配置文件
├── urls.py配置页面url
└── wsgi.py(Python Web Server Gateway Interface 服务器网关接口,python应用与Web服务器之间的接口,)
manage.py
如[email protected] ~]#python manage.py runserver(直接输入python manage.py可以列出命令选项)
settings.py
项目的总配置文件,包含了数据库、web应用、时间等各种配置文件
import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #项目的跟目录 # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = ‘qkotgzdcj-n!q#[email protected]!5$cuvqp3d=vrljrbuo48qvr5b‘ #启动项目所必须的安全码 # SECURITY WARNING: don‘t run with debug turned on in production! DEBUG = True #调试,打开后异常会反馈给用户页面 ALLOWED_HOSTS = [‘192.168.230.129‘] #只允许外界通过【】内的地址访问 # Application definition INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘zzb‘, ] #组成项目的应用,自己创建的应用需加进去 MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘, ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, ‘django.middleware.csrf.CsrfViewMiddleware‘, ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ] #中间件,自带的工具集 ROOT_URLCONF = ‘blog.urls‘ #url的根文件,指向urls.py TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [], ‘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‘, ], }, }, ] #模板(html文件)配置 WSGI_APPLICATION = ‘blog.wsgi.application‘ #把myblog当做一个模块 # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { ‘default‘: { # ‘ENGINE‘: ‘django.db.backends.sqlite3‘, # ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘blog‘, ‘USER‘:‘root‘, ‘PASSWORD‘:‘‘, ‘HOST‘:‘‘, ‘PORT‘:‘‘, ‘OPTIONS‘:{ ‘autocommit‘:True, }, } } #数据库配置,使用其他数据库需改动 # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { ‘NAME‘: ‘django.contrib.auth.password_validation.UserAttributeSimilarityValidator‘, }, { ‘NAME‘: ‘django.contrib.auth.password_validation.MinimumLengthValidator‘, }, { ‘NAME‘: ‘django.contrib.auth.password_validation.CommonPasswordValidator‘, }, { ‘NAME‘: ‘django.contrib.auth.password_validation.NumericPasswordValidator‘, }, ] #密码认证 # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = ‘en-us‘ TIME_ZONE = ‘UTC‘ USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = ‘/static/‘ #静态文件的地址 STATIC_ROOT = ‘/var/www/html/blog/zzb/static/‘
- 应用的目录结构
.├── admin.py (该应用的后台管理系统配置(django自带一个后台管理系统,每个应用都有各自的配置文件)
├── apps.py 该应用的一些配置,1.9版本后才有。
├── __init__.py
├── migrations 数据迁移模块
│ └── __init__.py(有这个文件说明它是一个模块)
├── models.py 数据模块(在其中创建数据表)使用ORM框架,类似于MVC结构中的Models(模型)
├── tests.py 自动测试模块,在这里编写测试脚本(语句)
└── views.py 执行响应的逻辑代码所在的模块,决定了接受web的请求后如何响应(项目中大部分在这里编写)
正式开始创建博客系统
搭建环境(建议源码安装,这里为了简便介绍yum | pip安装)
Python
- linux自带Python,无需安装,
- 低于2.7的版本与最新的Django不兼容
Django(自带一个小型的服务器)
安装(二选一)
- a) pip安装(需要本地有python-pip)
[[email protected] ~]#pip install Django==1.10.2
- b) 下载源码(执行效率更高),进入根目录执行[[email protected] ~]#python setup.py install
判断安装是否完成
[[email protected] ~]# python -m django –version
将Django部署到Apache服务器上
方法1, 直接配置
安装mod_wsgi(yum install mod_wsgi)
修改apache配置文件(点击跳转后续详解)
配置项目中wsgi (点击跳转后续详解)
方法2, 引入配置文件
- 不需要执行修改配置文件中的在最后添加一步(点击跳转至不需执行的步骤)
- 在项目/var/www/html/目录下添加/wsgi/django.wsgi文件,内容如下:
import os import sys import django.core.handlers.wsgi from django.conf import settings # Add this file path to sys.path in order to import settings sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), ‘..‘)) os.environ[‘DJANGO_SETTINGS_MODULE‘] = ‘blog.settings‘ sys.stdout = sys.stderr DEBUG = True application = django.core.handlers.wsgi.WSGIHandler()
- 在 /etc/httpd/conf.d 下 创建blogproject(自定义).conf
内容如下:
<VirtualHost *:80> WSGIScriptAlias / /var/www/html/wsgi/django.wsgi #与上面创建的目录相同 Alias /static/ /var/www/html/collectedstatic ServerName 192.168.230.129 #ServerName example.com #ServerAlias www.example.com <Directory /srv/lxyproject/collectedstatic> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> <Directory /var/www/html/wsgi/> Require all granted </Directory> ErrorLog /etc/httpd/logs/blogproject.error.log LogLevel warn </VirtualHost>
创建第一个项目
用django-admin创建项目
[[email protected] ~]#django-admin startproject blog(新命令django-admin) 会在/var/www/html/下生成一个新的文件夹blog
用manage.py创建应用
[[email protected] ~]#python manage.py startapp zzb
添加应用名到settings.py中的INSTALLED_APP里,
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘zzb‘, ]
修改settings.py,输入linux本机ip
ALLOWED_HOSTS = [‘192.168.230.129‘]
创建第一个页面(响应)
- 修改apache配置文件(/etc/httpd/conf/httpd.conf), 修改配置文件后重启apache
在最后添加:
LoadModule wsgi_module modules/mod_wsgi.soErrorLog "logs/error_log" <Directory /var/www/html/blog/blog> <Files wsgi.py> Require all granted </Files> </Directory>
- 配置wsgi.py,因为使用的不是django自带的服务器,而是apache,若配置相同则不需要修改
import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "blog.settings") application = get_wsgi_application()
- 编辑blog.views
# Create your views here. from django.http import HttpResponse def index(request): return HttpResponse(‘hello,world’)
每个函数必须返回一个响应,函数必须存在一个参数,一般约定为request,对应一个URL
- 配置urls.py(每个url都以url函数的形式写在urlpatterns列表中。三个参数(URL(正则),对应响应方法,名称zzb为应用名)
from django.conf.urls import url from django.contrib import admin import zzb.views as bv urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘,bv.index), ]
- 打开页面(192.168.230.129/index)
hellow,world
URL配置增强
- 修改blog下的url(注意url后面的/问题),引入include
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘,include(‘zzb.urls) ), ]
- 在app(zzb)下新建urls.py
from django.conf.urls import url from . import views urlpatterns = [ url(r‘^index/$‘,views.index), ]
- 浏览器输入地址: http://192.168.230.129/blog/index/
hello,world
创建第一个Templates(模板)
- 在APP根目录下创建名叫templates(小写)的目录,
- 在templates目录下创建以app名为名称的目录,将html文件放入其中(解决templates冲突)
- 在views.py中返回render()
from __future__ import unicode_literals from django.shortcuts import render # Create your views here. from django.http import HttpResponse def index(request): return render(request,‘index.html‘)
Models(模型)
一个model对应一张数据表,以类的形式表现,包含类一些基本字段以及数据的一些行为. ORM(object relation mapping)对象关系映射,不需要编写SQL语句
- 在settings.py中修改,使用MySQL代替django自带数据库.
DATABASES = { ‘default‘: { # ‘ENGINE‘: ‘django.db.backends.sqlite3‘, # ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘blog‘, ‘USER‘:‘root‘, ‘PASSWORD‘:‘‘, ‘HOST‘:‘‘, ‘PORT‘:‘‘, ‘OPTIONS‘:{ ‘autocommit‘:True, }, } }
- 在数据库中创建名为blog的数据库
- pip安装pymysql插件
- 修改blog/_init_.py,添加
import pymysql pymysql.install_as_MySQLdb()
- 应用根目录下创建models.py,并引入models模块,创建类,继承models.Model,类即是一张数据表,在类中创建字段
from __future__ import unicode_literals from django.db import models # Create your models here. class Article(models.Model): title = models.CharField(max_length=32, default=‘Title‘) content = models.TextField(null=True) def _unicode_ (self): return self.title
- 生成数据表
[[email protected] ~]#python manage.py makemigrations
[[email protected] ~]#python manage.py migrate(会在app/migrations/目录下生成移植文件)
可以通过执行[[email protected] ~]#python manage.py sqlmigrate 应用名 文件id(查看SQL语句)
- 往数据库中写入数据
- 取出数据
views.py中
1 # -*- coding: utf-8 -*- 2 from __future__ import unicode_literals 3 4 from django.shortcuts import render 5 6 # Create your views here. 7 from django.http import HttpResponse 8 from . import models 9 10 def index(request): 11 article = models.Article.objects.get(pk=1) 12 return render(request,‘zzb/index.html‘,{‘article‘:article})
- 页面呈现数据
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ article.title }}</h1> <h3>{{ article.content }}</h3> </body> </html>
Admin(自动化数据管理界面)
可直接在admin中管理数据库
- [[email protected] ~]#python manage.py createsuperuser
- 进入192.168.230.129/admin登录
- 更改语言,修改settings.py中LANGUAGE_CODE= ‘zh_Hans’
- 配置应用
在应用下的admin.py中引入自身的models模块(或者里面的模型类)
在应用目录下的admin.py中做如下修改
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.contrib import admin from models import Article # Register your models here. admin.site.register(Article)
- 修改数据默认显示的名称
编辑应用下models.py,在Article类下添加一个方法,根据Python版本(3/2.7)选择_str_(self)或_unicode_(self)
- 关于admin页面没有css样式的解决办法
1. 去djando的解压包里的/doc/howto/static-files中查看帮助文档,找到解决办法
2. 在应用目录下创建static目录,在settings.py中添加STATIC_ROOT=’你的ststic的文件夹地址’
3. 在urls.py中添加修改
urlpatterns = [ # ... the rest of your URLconf goes here ... ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
4. 执行python manage.py collectstatic
博客开发
博客主页面开发
index.html
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1> <a href="{% url ‘zzb:edit_page‘ 0 %}">新文章</a> </h1> {% for article in articles %} <a href="{% url ‘zzb:article_page‘ article.id %}">{{ article.title }}</a> <br/> {% endfor %} </body> </html>
博客文章页面开发
article_page.html
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>Article Page</title> </head> <body> <h1>{{ article.title }} </h1> <h3>{{ article.content }}</h3> <br/><br/> <a href="{% url ‘zzb:edit_page‘ article.id %}">修改文章</a> </body> </html>
博客编辑页面开发
edit_page.html
<DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Edit Page</title> </head> <body> <form action="{% url ‘zzb:edit_action‘ %}" method="post"> {% csrf_token %} {% if article %} <input type="hidden" name="article_id" value="{{ article.id }}"> <label>文章标题 <input type="text" name = "title" value="{{ article.title }}"/> </label> <br/> <label>文章内容 <input type="text" name = "content" value="{{ article.content }}"/> </label> <br/> {% else %} <input type="hidden" name="article_id" value="0"> <label>文章标题 <input type="text" name = "title" /> </label> <br/> <label>文章内容 <input type="text" name = "content" /> </label> <br/> {% endif %} <input type="submit" value="提交"/> </form> </body> </html>
views.py配置
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.shortcuts import render from django.http import HttpResponse from . import models def index(request): articles = models.Article.objects.all() return render(request, ‘zzb/index.html‘, {‘articles‘:articles}) def article_page(request, article_id): article = models.Article.objects.get(pk=article_id) return render(request,‘zzb/article_page.html‘,{‘article‘:article}) def edit_page(request,article_id): if str(article_id) == ‘0‘: return render(request,‘zzb/edit_page.html‘) article = models.Article.objects.get(pk=article_id) return render(request,‘zzb/edit_page.html‘,{‘article‘: article}) def edit_action(request): title = request.POST.get(‘title‘,‘TITLE‘) content = request.POST.get(‘content‘,‘CONTENT‘) article_id = request.POST.get(‘article_id‘,‘0‘) if str(article_id) == ‘0‘: models.Article.objects.create(title=title,content=content) articles = models.Article.objects.all() return render(request,‘zzb/index.html‘,{‘articles‘:articles}) article = models.Article.objects.get(pk=article_id) article.title = title article.content = content article.save() return render(request,‘zzb/article_page.html‘,{‘article‘:article})
url配置
from django.conf.urls import url from . import views urlpatterns = [ url(r‘^index/$‘, views.index), url(r‘^article/(?P<article_id>[0-9]+)/$‘, views.article_page, name=‘article_page‘), url(r‘^edit/(?P<article_id>[0-9]+)/$‘,views.edit_page, name=‘edit_page‘), url(r‘^edit/action/$‘,views.edit_action, name=‘edit_action‘), ]
Templates过滤器
过滤器属于django模板语言, 修改模板中的变量,从而显示不同内容
{{ value | filter }}
举例:{{ list_nums | length}} 表示list的长度
{{ value | filter | filter | filter }} 可叠加
使用过滤器简化edit_page.html
<DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Edit Page</title> </head> <body> <form action="{% url ‘zzb:edit_action‘ %}" method="post"> {% csrf_token %} <!--解决跨站请求伪造问题,POST表单需要添加这句--!> <input type="hidden" name="article_id" value="{{ article.id | default:‘0‘}}"> <!--default过滤器,默认值--!> <label>文章标题 <input type="text" name = "title" value="{{ article.title }}"/> </label> <br/> <label>文章内容 <input type="text" name = "content" value="{{ article.content }}"/> </label> <br/> <input type="submit" value="提交"/> </form> </body> </html>
Django Shell
python交互式命令行程序,自动引入项目环境,可以使用它和项目进行交互
启动django shell
pyhton manage.py shell
交互举例:
from blog.models import Article
Article.objects.all()
作用:1)调试工作 2)测试未知的方法
Admin增强
配置admin.py,使其显示更多内容
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.contrib import admin from models import Article class ArticleAdmin(admin.ModelAdmin): list_display = (‘title‘,‘content‘,‘pub_time‘) list_filter = (‘pub_time‘,) # Register your models here. admin.site.register(Article,ArticleAdmin)
配置models.py,增加时间参数
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models # Create your models here. class Article(models.Model): title = models.CharField(max_length=32, default=‘Title‘) content = models.TextField(null=True) pub_time = models.DateTimeField(null=True) def _unicode_ (self): return self.title
2017-07-29/22:26:38