Django教程01-全流程
目录
1.django简介
mtv模式
- model模型: 负责业务对象与数据库的对象
- template模板: 负责如何把页面展示给用户
- view视图:负责业务逻辑,并在合适的时候调用model和template
注意:django还有一个url分发器,它的作用是将一个个的url的页面请求分发给不同的view处理,view再调用相应的model和template
1.1. django安装
pip install django import django print(django.get_version()) # 2.1.7
2. 创建一个基础的django项目
2.1. 初始化项目
在你希望创建django项目的文件夹下输入
django-admin startproject project
mysite项目下面有如下的文件
project/ manage.py # 管理 django 项目的命令行工具,可以使用多种方式和django项目进行交互 project/ # 纯 python 包。它的名字就是当你引用它内部任何东西时需要用到的 python 包名(project.urls) __init__.py # 一个空文件,告诉 python 这个目录应该被认为是一个 python 包 settings.py # django 项目的配置文件 urls.py # django 项目的 url 声明,网站目录 wsgi.py # 项目的运行在 wsgi 兼容的web服务器上的入口
在mysite文件夹内运行
python manage.py runserver # 启动了一个自带的简易服务器
2.2. 设计数据库
2.2.1. 设计目标表
本文中主要设计两个表:
- 班级表
id | 班级名称 | 成立时间 | 女生总数 | 男生总数 | 是否删除 |
---|---|---|---|---|---|
1 | gname | gdate | ggirlnum | gboynum | isdelete |
- 学生表
id | 学生姓名 | 学生性别 | 学生年龄 | 学生简介 | 所属班级 | 是否删除 |
---|---|---|---|---|---|---|
1 | sname | sgender | sage | scontend | sgrade | isdelete |
2.2.1. 创建一个数据库
在mysql终端中创建一个dj_test
的数据库
create database dj_test;
2.2.2. 配置mysql数据库
django默认使用的sqlite数据库, 在settings.py
中更改数据库配置为
databases = { 'default': { 'engine': 'django.db.backends.mysql', 'name': 'dj_test', 'user': 'root', 'password': '***', 'host': 'localhost', 'port': '3306', } }
2.3. 创建应用
在一个项目中可以创建多个应用,每个应用进行一种业务逻辑,互不影响
在project
目录下,创建新的应用
python manage.py startapp myapp
此时多了一个myapp
的一个新的文件夹
migrations/ __init__.py admin.py # 站点配置 apps.py models.py # 模型 tests.py views.py # 视图
2.4. 激活应用
将应用配置到项目中,在settings.py
中将myapp
应用加入到installed_apps
installed_apps = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp' ]
2.5. 定义模型
- 在
models.py
中进行定义模型,有一个数据表就对应有一个模型,本文中有两个数据表,需要两个模型 - 用于和数据库交互
- 模型类必须继承
models.model
类,类的属性对应于表的字段 - 主键自动添加
from django.db import models # create your models here. class grades(models.model): gname = models.charfield(max_length=20) gdate = models.datefield() ggirlnum = models.integerfield() gboynum = models.integerfield() isdelete = models.booleanfield() class students(models.model): # 1(班级)对多(学生),外键写在多的里面 sname = models.charfield(max_length=20) sgender = models.booleanfield(default=true) sage = models.integerfield() scontend = models.charfield(max_length=20) sgrade = models.foreignkey('grades', on_delete=models.cascade) isdelete = models.booleanfield(default=false)
2.6. 根据模型在数据库中生成表
第一步: 生成迁移文件
python manage.py makemigrations
- 在
myapp/migrations
下面生成的一个迁移文件,但是没有生成表
第二步: 执行迁移
python manage.py migrate
生成以应用名_类名
为表格名
在数据库中就生成了以下的表格
+----------------------------+ | tables_in_dj_test | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | | myapp_grades | | myapp_students | +----------------------------+
注意:以后对于数据库的操作,是通过模型类的对象来完成,一个对象对应一条数据
2.7. 测试数据操作
进入到python shell
环境
python manage.py shell
>>> from myapp.models import grades, students >>> from django.utils import timezone >>> from datetime impor *
查询所有数据:
通过模型类的objects属性查询
类名.objects.all()
>>> grades.objects.all()
添加数据:
本质: 创建一个模型类的对象实例
grade1 = grades() grade1.gname = 'python04' grade1.gdate = datetime(year=2017,month=7,day=17) grade1.ggirlnum = 3 grade1.gboynum = 70 grade2 = grades() grade2.gname = 'python02' grade2.gdate = datetime(year=2017,month=7,day=20) grade2.ggirlnum = 5 grade1.gboynum = 32 grade1.save() # 存到数据库中 grade2.save()
查看数据库select * from myapp_grades
得到以下结果
+----+----------+------------+----------+---------+----------+ | id | gname | gdate | ggirlnum | gboynum | isdelete | +----+----------+------------+----------+---------+----------+ | 1 | python01 | 2017-07-17 | 3 | 70 | 0 | | 2 | python02 | 2017-07-20 | 5 | 32 | 0 | +----+----------+------------+----------+---------+----------+
条件查询数据:
类目.objects.get(pk=index)
g = grades.objects.get(pk=2)
修改数据
修改grade2的姓名
g = grades.objects.get(pk=2) g.gname = 'python-666' g.save()
修改结果为:
| 2 | python-666 | 2017-07-20 | 5 | 32 | 0 |
删除数据
g.delete() # 物理删除
表关联
因为学生表和班级表有关系,我们可以在shell中测试
stu = students() stu.sname = 'zhangsan' stu.sgender = false stu.sage = 20 stu.scontend = 'my name is zhangsan' stu.sgrade = grade2 stu1 = students() stu1.sname = 'lisi' stu1.sage = 20 stu1.scontend = 'my name is lisi' stu1.sgrade = grade2 stu1.save() stu.save()
此时students中有两条数据
+----+----------+---------+------+---------------------+----------+-----------+ | id | sname | sgender | sage | scontend | isdelete | sgrade_id | +----+----------+---------+------+---------------------+----------+-----------+ | 1 | zhangsan | 0 | 20 | my name is zhangsan | 0 | 2 | | 2 | lisi | 1 | 20 | my name is lisi | 0 | 2 | +----+----------+---------+------+---------------------+----------+-----------+
2.7.1. 获取某个班级的所有学生
对象名.关联的类名小写_set.all()
>>> grade2.students_set.all() >>> <queryset [<students: students object (1)>, <students: students object (2)>]>
2.7.2. 在班级中创建一个学生
不用save,直接添加到数据库中
stu3 = grade2.students_set.create(sname='wangwu',sgender=true,scontend='my name is wangwu',sage=52)
+----+----------+---------+------+---------------------+----------+-----------+ | id | sname | sgender | sage | scontend | isdelete | sgrade_id | +----+----------+---------+------+---------------------+----------+-----------+ | 1 | zhangsan | 0 | 20 | my name is zhangsan | 0 | 2 | | 2 | lisi | 1 | 20 | my name is lisi | 0 | 2 | | 3 | wangwu | 1 | 52 | my name is wangwu | 0 | 2 | +----+----------+---------+------+---------------------+----------+-----------+
2.8. 启动服务器
格式:
python manage.py runserver ip:port
ip: 不写的话,代表本机ip
port: 默认8000
说明
django写的轻量级服务器,只在开发测试中使用
3. django的admin站点管理
有一个可视化界面,用于添加、修改、删除内容
3.1. 配置admin应用
在setting.py
文件的installed_app
中添加django.contrib.admin
(默认添加好了)
3.2. 创建管理员用户
python manage.py createsuperuser c:\users\haochen\desktop\django\project>python manage.py createsuperuser username (leave blank to use 'haochen'): email address: 123@qq.com password: password (again):
启动管理界面
启动服务,进入到http://127.0.0.1:8000/admin
3.4. 管理数据表
修改admin.py
属性 | 类型 | 说明 |
---|---|---|
list_display | 列表页属性 | 显示字段 |
list_filter | 过滤器来过滤字段 | |
search_fields | 搜索字段 | |
list_per_page | 分页 | |
fields | 添加修改页 | 规定属性先后顺序 |
fieldssets | 给属性分组(和fields不能同时使用) |
from django.contrib import admin # register your models here. from .models import grades,students # 注册 # 自定义班级页面 class studentsinfo(admin.tabularinline): model = students extra = 2 class gradesadmin(admin.modeladmin): # 在创建班级的时候,可以同时添加两个学生 inlines = [studentsinfo] # 列表页属性 list_display = ['pk','gname','gdate','ggirlnum','gboynum','isdelete'] list_filter = ['gname'] search_fields = ['gname'] list_per_page = 5 # 添加,修改页属性 # fields = [] fieldsets = [ ("number computations", {"fields": ['ggirlnum', 'gboynum']}), ("base information", {"fields": ['gname', 'gdate', 'isdelete']}) ] class studentsadmin(admin.modeladmin): # 修复布尔值显示问题 def gender(self): if self.sgender: return "male" else: return "female" gender.short_description = "gender" list_display = ['pk','sname','sage',gender, 'scontend', 'sgrade', 'isdelete'] list_per_page = 2 admin.site.register(grades,gradesadmin) admin.site.register(students,studentsadmin)
4. view的基本使用
- 视图对web请求进行回应
- 就是一个python函数,在
views.py
4.1. 配置url控制器
修改外部urls
修改mysite/mysite
目录下的urls.py
文件
from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), # 当页面中只输入主页面时,就会定位到myapp.urls中的url # 匹配真正的视图应该在myapp/urls中完成 path('', include('myapp.urls')) ]
修改appurls
在mysite目录下创建urls.py
from django.urls import path,include from . import views urlpatterns = [ path(r'', views.index), path(r'<int:num>/', views.detail, name='num'), ]
4.2. 定义视图
在views.py
定义
from django.http import httpresponse def index(request): return httpresponse("school is on time") def detail(request, num): return httpresponse("details-%s"%(num))
5. 模板的基本使用
模板是html页面,可以根据视图传递过来的数据进行填充
需求: 输入http://127.0.0.1:8000/grades
显示所有班级
5.1. 创建模板
创建templates+myapp
文件夹,和manage.py
同级,用于存放和myapp有关的模板
5.2. 配置模板路径
修改settings.py
文件的templates
templates = [ { 'backend': 'django.template.backends.django.djangotemplates', 'dirs': [os.path.join(base_dir, 'templates')], ... } ]
5.3. 创建html模板
- 定义
grades.html
和students.html
- 模板语法
{{输出值,可以是变量,也可以是对象.属性}} {%执行python代码段%}
5.3.1. 写grades模板
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>班级信息</title> </head> <body> <h1>班级信息列表</h1> <ul> <!--传过来的是对象[python04,python05,python06]--> {%for grade in grades%} <li> <a href="#">{{grade.gname}}</a> </li> {%endfor%} </ul> </body> </html>
5.4. 定义视图和配置url
- url
urlpatterns = [ path('', views.index), path('<int:num>/', views.detail, name='num'), path('grades/', views.grades, name = 'grades') ]
- view
from .models import grades,students def grades(request): # 去模板中取数据 gradeslist = grades.objects.all() # 将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器 return render(request, 'myapp/grades.html', {"grades": gradeslist})
5.5. 测试
输入http://127.0.0.1:8000/grades
,可以拿到以下数据
5.6. 实例: 定义student模板
- 定义view
def students(request): studentlist = students.objects.all() return render(request, 'myapp/students.html', {"students": studentlist})
- 定义url
urlpatterns = [ path('', views.index), path('<int:num>/', views.detail, name='num'), path('grades/', views.grades, name = 'grades'), path('students/', views.students, name = 'students') ]
- 定义模板
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>学生页面</title> </head> <body> <h1>学生信息列表</h1> <ul> <!--传过来的是对象[python04,python05,python06]--> {%for student in students%} <li> {{student.sname}}}--{{student.scontend}} </li> {%endfor%} </ul> </body> </html>
5.7. 查看每个班级下的学生
- 修改grades。html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>班级信息</title> </head> <body> <h1>班级信息列表</h1> <ul> <!--传过来的是对象[python04,python05,python06]--> {%for grade in grades%} <li> <a href="{{grade.id}}">{{grade.gname}}</a> </li> {%endfor%} </ul> </body> </html>
- 定义view
def gradesstudents(request, number): # 获得对应的班级对象 grades = grades.objects.get(pk=number) # 获得班级下的所有学生列表 studentslist = grades.students_set.all() return render(request, 'myapp/students.html', {"students": studentslist})
- 配置url
urlpatterns = [ path('', views.index), path('<int:num>/', views.detail, name='num'), path('grades/', views.grades, name = 'grades'), path('students/', views.students, name = 'students'), path('grades/<int:number>', views.gradesstudents, name = 'number') ]
6. 注意事项
6.1. 重新迁移问题
删除迁移文件:
myapp/migrations
下除了__init__
外全部删除删除数据库: 在mysql中删除数据库