当前位置: 移动技术网 > IT编程>脚本编程>Python > Django教程01-全流程

Django教程01-全流程

2019年03月30日  | 移动技术网IT编程  | 我要评论

专业硕士和学术硕士的区别,旌德社区,对联左右

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

本文中主要设计两个表:

  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,可以拿到以下数据

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>

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网