欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django教程01-全流程

程序员文章站 2022-05-14 08:57:48
[TOC] 1.Django简介 MTV模式 Model模型: 负责业务对象与数据库的对象 Template模板: 负责如何把页面展示给用户 View视图:负责业务逻辑,并在合适的时候调用Model和Template 注意: Django还有一个url分发器,它的作用是将一个个的URL的页面请求分发 ......

1.django简介

mtv模式

Django教程01-全流程

  • 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-全流程

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-全流程

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中删除数据库