Django介绍
什么是Django:Django是一个基于Python的高级web开发框架,它能够让开发人员进行高效且快速的开发。高度集成(不同重复造轮子),免费且开源。
搭建环境:安装Python,Python官网下载安装包安装即可,过程略。
安装Django:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Django==2.2.5
或者下载源码tar包,进入解压目录执行 python setup.py install
创建项目:在Windows命令行下(在 Linux 下也适用),
cd Desktop mkdir myblog cd myblog django-admin startproject myblog #未报错则创建成功启动项目:
命令行下,
cd myblog python manage.py runserver 9999
浏览器访问 127.0.0.1:9999 即可访问django默认页
Django默认 Debug=True ,即在调试模式下,后面无须手动重启服务器,除非代码报错服务器宕掉。
Django Shell
Django Shell是一个Python的交互式命令行程序,它自动引入了项目环境,我们可以使用它与项目进行交互。
在命令行下,执行 python manage.py shell 进入Django Shell。
在Django Shell下,可以尝试一下 Django 为你创建的各种 API。通常使用Django Shell进行一些调试工作,测试未知的方法。
创建应用
PyCharm打开项目:使用PyCharm打开桌面上的目录myblog下的myblog目录,有个与 manage.py 同级的myblog目录,其中有这些文件:
wsgi.py python应用与wen服务器之间的接口 urls.py url配置文件,所有页面都需要配置url settings.py 项目的总配置文件,包含数据库、web应用、时间等配置 __init__.py python中声明模块的文件,内容默认为空创建应用:
打开命令行,进入项目中 manage.py 所在的目录,执行:
python manage.py startapp blog
并添加应用名到 settings.py 中的 INSTALLED_APPS 中。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog',]
应用名不能与python中模块名相同,否则会创建失败。
新生成的与 manage.py 同级的blog目录中有这些文件:
migrations 数据移植(迁移)模块,内容自动生成 __init__.py __init__.py admin.py 该应用的后台管理系统配置 apps.py 该应用的一些配置 models.py 数据模块,使用ORM框架,类似于MVC结构中的Models tests.py 自动化测试模块,在这里编写测试脚本 views.py 执行响应的代码所在模块,代码逻辑处理的位置创建一个页面响应:
views.py
from django.shortcuts import render# Create your views here.from django.http import HttpResponsedef index(request): return HttpResponse('Hello World')
urls.py
from django.contrib import adminfrom django.urls import pathimport blog.views as bv urlpatterns = [ path('admin/', admin.site.urls), path('index/', bv.index),]
浏览器访问 127.0.0.1:9999/index/
每个响应对应一个函数,函数必须返回一个响应。函数必须存在一个参数,一般约定为request,每个响应(函数)对应一个url。
每个url都以url的形式写出来,url函数放在urlpatterns列表中。url函数三个参数:url(正则),对应方法,名称。
重新配置url:urls.py
from django.contrib import adminfrom django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include('blog.urls')),]
同时在blog应用目录下新增 urls.py
from django.urls import pathfrom . import views urlpatterns = [ path('index/', views.index),]
浏览器访问 127.0.0.1:9999/blog/index/
项目的根urls.py针对APP配置的url名称,是该APP所有url的总路径。
开发Template
Django的Template就是一个个的HTML文件,使用了Django模板语言(DTL),template可以使用第三方模板(如Jinja2)。
开发一个template:在应用blog目录下创建名为 Templates 的目录,在Templates目录下创建index.html文件。
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1>Hello, Blog!h1>body>html>
接着在views.py中返回 render()
from django.shortcuts import render# Create your views here.from django.http import HttpResponsedef index(request): return render(request, 'index.html')
浏览器访问 127.0.0.1:9999/blog/index/
DTL初步使用:
render() 函数中支持一个dict类型参数,该字典是后台传递到模板的参数,key为参数名,在模板中直接通过 {{参数名}} 来使用参数。
views.py
from django.shortcuts import render# Create your views here.from django.http import HttpResponsedef index(request): return render(request, 'index.html', {'hello': 'Hello, Blog!!!'})
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1>{{ hello }}h1>body>html>
浏览器访问 127.0.0.1:9999/blog/index/
Django查找template:
Django按照 INSTALLED_APPS 中的添加顺序查找template,不同APP下Templates目录中的同名html文件会造成冲突。
解决冲突:
在APP的Templates目录下创建以APP名为名称的目录,将html文件放入该目录下。
views.py
from django.shortcuts import render# Create your views here.from django.http import HttpResponsedef index(request): return render(request, 'blog/index.html', {'hello': 'Hello, Blog123!'})
浏览器访问 127.0.0.1:9999/blog/index/
编写Models
通常,一个Model对应数据库的一张数据表。Django中Models以类的形式表现,它包含一些基本字段以及数据的一些行为。
ORM即对象关系映射(Object Relation Mapping),实现了对象和数据库之间的映射,隐藏了数据访问的细节,不需要编写SQL语句。
编写models:在应用blog目录下的 models.py(默认已引入models模块)中创建类,继承 models.Model ,该类即为一张数据表,在类中创建属性(变量)即相当于在数据表中创建字段。
models.py
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)生成数据表
命令行下进入 manage.py 同级目录,执行
python manage.py makemigrations app名(可选) python manage.py migrate
这里可以不加应用名,就是为项目下的所有应用生成数据表。
Django会自动在 app名/migrations/ 目录下生成移植文件。命令行下查看SQL语句,执行
python manage.py sqlmigrate app名 文件id
查看并编辑db.sqlite3:
使用第三方软件SQLite EXpert Personal,打开与 manage.py 同级的db.sqlite3文件。
找到blog_article这个表,使用 + 添加一行:title为 Hello ,content为 Hello, Blog! ,再使用 √ 保存即可。
页面呈现数据:
views.py
from django.shortcuts import renderfrom . import modelsdef index(request): #获取主键为1的article article = models.Article.objects.get(pk=1) return render(request, 'blog/index.html', {'article': article})
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1>{{article.title}}h1><h3>{{article.content}}h3>body>html>
浏览器访问 127.0.0.1:9999/blog/index/
Admin
Admin是Django自带的一个功能强大的自动化数据管理界面,可授权用户直接在Admin中管理数据库。
创建超级用户:python manage.py createsuperuser
浏览器访问 127.0.0.1:9999/admin/ ,输入超级用户的账号密码登录Admin。
修改Admin界面为中文:修改setting.py中 LANGUAGE_CODE = 'zh_Hans' 即可。
配置Admin:
在应用blog目录下的admin.py中引入自身的models模块(或models模块中的类)。
admin.py
from django.contrib import admin# Register your models here.from . import models admin.site.register(models.Article)
刷新浏览器
修改文章内容
访问 127.0.0.1:9999/blog/index/
修改数据默认显示名称:
在Admin首页点击 Articles 之后,会发现数据显示名称为 Article object (1) ,这不是我们想要的。
models.py
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 __str__(self): return self.title
刷新浏览器
完善博客
页面概要:需要有博客的主页面、博客文章内容页面及博客撰写页面。
主页面内容:文章标题列表(超链接)、发布博客按钮(超链接)
列表编写思路:取出数据库中所有文章对象 将所有文章对象打包成列表,传递到前端 前端页面把文章以标题超链接的形式逐个列出主页面开发:
views.py
from django.shortcuts import renderfrom . import modelsdef index(request): articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1> <a href="">新的文章a>h1>{% for article in articles %} <a href="">{{ article.title }}a> <br/>{% endfor %}body>html>
访问 127.0.0.1:9999/blog/index/
文章页面开发:
views.py
from django.shortcuts import renderfrom . import modelsdef index(request): articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})def article_page(request, article_id): article = models.Article.objects.get(pk=article_id) return render(request, 'blog/article_page.html', {'article': article})
包含index.html的目录下创建article_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Article Pagetitle>head><body><h1>{{ article.title }}h1><br/><h3>{{ article.content }}h3><br/><br/><a href="">修改文章a>body>html>
应用blog下的urls.py
from django.urls import path, re_pathfrom . import views urlpatterns = [ path('index/', views.index), re_path(r'^article/(?P[0-9]+)$', views.article_page),]
访问 127.0.0.1:9999/blog/article/1
url正则中的组名必须和views.py中的 article_page() 方法的参数名一致。
补全主页面超链接的目的地:项目的urls.py
from django.contrib import adminfrom django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include(('blog.urls'), namespace='blog')),]
应用blog的urls.py
from django.urls import path, re_pathfrom . import views app_name = 'blog'urlpatterns = [ path('index/', views.index), re_path(r'^article/(?P[0-9]+)$', views.article_page, name='article_page'),]
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1> <a href="">新的文章a>h1>{% for article in articles %} <a href="{% url 'blog:article_page' article.id %}">{{ article.title }}a> <br/>{% endfor %}body>html>
访问 127.0.0.1:9999/blog/index/
点击文章名,自动跳转到文章页面。
撰写页面开发:views.py
from django.shortcuts import renderfrom . import modelsdef index(request): articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})def article_page(request, article_id): article = models.Article.objects.get(pk=article_id) return render(request, 'blog/article_page.html', {'article': article})def edit_page(request): return render(request, 'blog/edit_page.html')def edit_action(request): title = request.POST.get('title', 'TITLE') content = request.POST.get('content', 'CONTENT') models.Article.objects.create(title=title, content=content) articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})
应用blog的urls.py
from django.urls import path, re_pathfrom . import views app_name = 'blog'urlpatterns = [ path('index/', views.index), re_path(r'^article/(?P[0-9]+)$', views.article_page, name='article_page'), re_path(r'^edit/$', views.edit_page, name='edit_page'), re_path(r'^edit/action$', views.edit_action, name='edit_action'),]
包含index.html的目录下创建edit_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Edit Pagetitle>head><body><form action="{% url 'blog:edit_action' %}" method="post"> {% csrf_token %} <label>文章标题 <input type="text" name="title"/> label> <br/> <label>文章内容 <input type="text" name="content"/> label> <br/> <input type="submit" value="提交"/>form>body>html>
访问 127.0.0.1:9999/blog/edit/
输入文章标题及内容后提交,自动跳转到博客主页面
补全 新文章 的超链接:
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1> <a href="{% url 'blog:edit_page' %}">新的文章a>h1>{% for article in articles %} <a href="{% url 'blog:article_page' article.id %}">{{ article.title }}a> <br/>{% endfor %}body>html>补全 修改文章 的超链接:
views.py
from django.shortcuts import renderfrom . import modelsdef index(request): articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})def article_page(request, article_id): article = models.Article.objects.get(pk=article_id) return render(request, 'blog/article_page.html', {'article': article})def edit_page(request, article_id): if str(article_id) == '0': return render(request, 'blog/edit_page.html') article = models.Article.objects.get(pk=article_id) return render(request, 'blog/edit_page.html', {'article': article})def edit_action(request): title = request.POST.get('title', 'TITLE') content = request.POST.get('content', 'CONTENT') models.Article.objects.create(title=title, content=content) articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})
应用blog的usls.py
from django.urls import path, re_pathfrom . import views app_name = 'blog'urlpatterns = [ path('index/', views.index), re_path(r'^article/(?P[0-9]+)$', views.article_page, name='article_page'), re_path(r'^edit/(?P[0-9]+)$', views.edit_page, name='edit_page'), re_path(r'^edit/action$', views.edit_action, name='edit_action'),]
article_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Article Pagetitle>head><body><h1>{{ article.title }}h1><br/><h3>{{ article.content }}h3><br/><br/><a href="{% url 'blog:edit_page' article.id %}">修改文章a>body>html>
index.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Titletitle>head><body><h1> <a href="{% url 'blog:edit_page' 0 %}">新的文章a>h1>{% for article in articles %} <a href="{% url 'blog:article_page' article.id %}">{{ article.title }}a> <br/>{% endfor %}body>html>
edit_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Edit Pagetitle>head><body><form action="{% url 'blog:edit_action' %}" method="post"> {% csrf_token %} {% if article %} <label>文章标题 <input type="text" name="title" value="{{ article.title }}"/> label> <br/> <label>文章内容 <input type="text" name="content" value="{{ article.content }}"/> label> <br/> {% else %} <label>文章标题 <input type="text" name="title"/> label> <br/> <label>文章内容 <input type="text" name="content"/> label> <br/> {% endif %} <input type="submit" value="提交"/>form>body>html>
访问 127.0.0.1:9999/blog/article/1 ,点击 修改文章
补全 提交 的超链接:
views.py
from django.shortcuts import renderfrom . import modelsdef index(request): articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles})def article_page(request, article_id): article = models.Article.objects.get(pk=article_id) return render(request, 'blog/article_page.html', {'article': article})def edit_page(request, article_id): if str(article_id) == '0': return render(request, 'blog/edit_page.html') article = models.Article.objects.get(pk=article_id) return render(request, 'blog/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 article_id == '0': models.Article.objects.create(title=title, content=content) articles = models.Article.objects.all() return render(request, 'blog/index.html', {'articles': articles}) article = models.Article.objects.get(pk=article_id) article.title, article.content = title, content article.save() return render(request, 'blog/article_page.html', {'article': article})
edit_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Edit Pagetitle>head><body><form action="{% url 'blog: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>
访问 127.0.0.1:9999/blog/index ,点击 新文章 ,任意填写标题与内容后提交,然后点开这篇文章修改
使用Templates过滤器
使用过滤器:{{ value | filter }} {{ value | filter1 | filter2 | filter3 |... }} #过滤器可叠加
edit_page.html
<html lang="en"><head> <meta charset="UTF-8"> <title>Edit Pagetitle>head><body><form action="{% url 'blog:edit_action' %}" method="post"> {% csrf_token %} <input type="hidden" name="article_id" value="{{ article.id | default:'0' }}"/> <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>
使用过滤器可以大大减少代码量。