基本流程
创建工程
1 | django-admin startproject mysite # mysite为工程名 |
此时的文件目录结构:1
2
3
4
5
6
7mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
- mysite/: 整个项目的容器,没有太大意义,名字可以随意更改
- manage.py: 命令行工具,用来管理Django项目
- mysite/: 当前Django工程所使用的Python包
- __init__.py: 表明当前文件夹是一个Python包
- settings.py: 配置文件
- urls.py: 路由配置文件
- wsgi.py: 兼容WSGI的Web服务入口
运行工程
1 | python manage.py runserver |
创建应用程序
工程(Project)和程序(App): 应用程序是真正工作的组件,例如一个博客系统或者投票系统。工程师包含网站配置信息和应用程序等的集合,一个工程可以包含多个应用程序,而一个应用程序可以属于多个工程。1
python manage.py startapp polls # 创建一个名为polls的投票程序
polls的目录结构:1
2
3
4
5
6
7
8
9polls\
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
配置数据库以及创建模型
使用Django自带的数据库SQLite。
现在,我们来定义模型model,模型本质上就是数据库表的布局,再附加一些元数据。
Django通过自定义Python类的形式来定义具体的模型,每个模型的物理存在方式就是一个Python的类Class,每一个类都是django.db.models.Model的子类。每一个字段都是Field类的一个实例,例如用于保存字符数据的CharField和用于保存时间类型的DateTimeField,它们告诉Django每一个字段保存的数据类型。每个模型代表数据库中的一张表,每个类的实例代表数据表中的一行数据,类中的每个变量代表数据表中的一列字段。
Django通过模型,将Python代码和数据库操作结合起来,实现对SQL查询语言的封装。也就是说,你可以不会管理数据库,可以不会SQL语言,你同样能通过Python的代码进行数据库的操作。Django通过ORM对数据库进行操作,奉行代码优先的理念,将Python程序员和数据库管理员进行分工解耦。
示例代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14# polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
可以在每个Field中使用一个可选的第一位置参数用于提供一个人类可读的字段名,让你的模型更友好,更易读,并且将被作为文档的一部分来增强代码的可读性,如例子中的pub_date。
使用ForeignKey定义了一个外键关系。它告诉Django,每一个Choice关联到一个对应的Question(注意要将外键写在‘多’的一方)。Django支持通用的数据关系:一对一,多对一和多对多,如例子中的question。
启用模型
把polls加入mysite/settings.py中的INSTALLED_APPS让项目知道该应用的存在。
运行命令$ python manage.py makemigrations polls
将数据模型的改动保存为一个’migration’
运行命令$ python manage.py migrate
对数据库执行真正的迁移动作。在这一步中会自动生成表,表明为“应用名_模型名(小写)”的组合,自动添加主键id并且按照惯例在外键字段名上附加“_id”。
开发视图
Django的视图是负责页面展示的重要模块,用于处理网站业务逻辑。
打开polls/view.py文件,每个视图至少做两件事之一:返回一个包含请求页面的HttpResponse对象或者弹出一个类似Http404的异常。其它的则自己定义。
render()方法: 从Django.shortcuts导入render,将加载模板、传递参数、返回HttpResponse对象整合一起。第一个位置参数是请求对象(就是view函数的第一个参数),第二个参数是模板,第三个参数是字典,包含需要传递给模板的数据。最后render函数返回一个经过字典数据渲染过的模板封装而成的HttpResponse对象。例如:1
2
3
4def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
创建视图后,为了能够访问它,需要在URL中添加路由映射。在polls中创建文件urls.py:1
2
3
4
5from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
接下来需要在根目录的urls.py中引用polls/urls.py,修改mysite/urls.py:1
2
3
4
5
6
7from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
上面代码中include()方法可以用来引用其他URLconfs(urls.py)。出了admin.site.urls之外,在任何时候都应该使用include()方法引用其他路由模块。
模板系统
Django提供的模板系统可以解耦视图和模板之间的硬连接。
首先,在polls目录下创建一个新的templates目录,Django会在它里面查找模板文件。
项目的 TEMPLATES配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 “templates” 子目录。这就是为什么尽管我们没有像在第二部分中那样修改 DIRS 设置,Django 也能正确找到 polls 的模板位置的原因。
在templates目录中,再创建一个新的子目录名叫polls,进入该子目录,创建一个新的html文件index.html。换句话说,你的模板文件应该是polls/templates/polls/index.html。因为 Django 会寻找到对应的app_directories ,所以你只需要使用polls/index.html就可以引用到这一模板了。
在视图view.py中通过render()向模板中的页面传递的上下文变量可以直接使用,例如在detail()视图里通过return render(request, 'polls/detail.html', {'question': question})
传递的question在模板polls/detail.html中通过question.question_text
使用
后台管理
运行命令$ python manage.py createsuperuser
创建一个可以登录admin站点的用户,填入所需信息后通过http://127.0.0.1:8000/admin/即可访问。
随后为了让应用的信息可以在后台显示,打开polls/admin.py注册投票应用:1
2
3
4from django.contrib import admin
from .models import Question
admin.site.register(Question)
参考资料
李健.《Django 2.0入门与实践》.清华大学出版社
刘江的博客教程
更新 2019-08-15
使用MySQL的配置方案
./settings.py:1
2
3
4
5
6
7
8
9
10 DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'NewTest',
'HOST': '127.0.0.1',
'USER': 'root',
'PASSWORD': 'pwd',
'PORT': '3306',
}
}
记载数据库驱动
./init.py:1
2import pymysql
pymysql.install_as_MySQLdb() # 完成数据库的驱动加载
解决mysqlclient版本问题
base.py 中搜索:1
version = Database.version_info
行内添加一个pass
1 | raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.version) |
如下:1
2
3
4
5
6
7
8if version < (1, 3, 13):
pass
'''
raise ImproperlyConfigured(
'mysqlclient 1.3.13 or newer is required; you have %s.'
% Database.__version__
)
'''
保存关闭并打开 operations.py搜索1
query = query.decode(errors='replace')
decode换为encode:1
query = query.encode(errors='replace')
其他
使用MySQL要注意自己创建数据库1
CREATE DATABASE <NAME>;