目录

1.Django简介

MTV模式

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

Django教程01-全流程 Python 第1张

  • 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. 设计目标表

本文中主要设计两个表:

  1. 班级表
ID 班级名称 成立时间 女生总数 男生总数 是否删除
1 gname gdate ggirlnum gboynum isDelete
  1. 学生表
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.htmlstudents.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,可以拿到以下数据

Django教程01-全流程 Python 第2张

5.6. 实例: 定义student模板

  1. 定义view
def students(request):
    studentList = Students.objects.all()
    return render(request, 'myApp/students.html', {"students": studentList})
  1. 定义url
urlpatterns = [
    path('', views.index),
    path('<int:num>/', views.detail, name='num'),
    path('grades/', views.grades, name = 'grades'),
    path('students/', views.students, name = 'students')
]
  1. 定义模板
<!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>

Django教程01-全流程 Python 第3张

5.7. 查看每个班级下的学生

  1. 修改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>
  1. 定义view
def gradesStudents(request, number):
    # 获得对应的班级对象
    grades = Grades.objects.get(pk=number)
    # 获得班级下的所有学生列表
    studentsList = grades.students_set.all()
    return render(request, 'myapp/students.html', {"students": studentsList})
  1. 配置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中删除数据库

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄