学习 Python Django

书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。

导读:本篇文章讲解 学习 Python Django,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

学习 Python Django

学习 Django

1. 初识Django命令

(1). 基本命令

命令 作用
startproject 启动Django项目
startapp 启动Django应用
check 校验项目完整性
runserver 运行项目
shell Django Shell
test 执行Django测试用例

(2). 数据库相关命令

命令 作用
makemigrations 创建模型变更的迁移文件
migrate 执行上一个makemigrations命令创建的迁移文件
dumpdata 把数据库数据导出到文件
loaddata 把文件数据导入数据库

2. 初识Django项目

(1). 创建项目

django-admin startproject 项目名字
文件 作用
settings.py Django项目配置文件
urls.py Django项目路由文件
wsgi.py Django项目作为wsgi应用文件
manage.py Django项目管理文件

(2). 启动项目

python manage.py runserver

3. 初识Django应用

(1). Django应用

一个Django项目包含一组配置和若干个Django应用

一个Django项目就是一个基于Django的Web应用

一个Django应用就是一个可重用的Python软件包

每个应用可以自己管理模型、视图、模板、路由和静态文件等

学习 Python Django

应用可以重复包含

(2). 创建应用

python manage.py startapp 应用名称

(3). 应用目录

文件 作用
views.py 视图处理
models.py 定义应用模型
admin.py 定义模块管理
apps.py 声明应用
tests.py 编写测试用例
urls.py (自行创建) 管理应用路由

4. Django视图

使用Django视图编写 hello world 函数

1). 在Django应用的views.py文件中创建视图函数

首先要导入模块

from django.http import HttpResponse


def helloWorld (request):
    return HttpResponse('hello world')

2). 应用层面的路由配置: 在Django应用的urls.py文件中 配置路由绑定试图函数和url

这是配置应用层面的路由

import 应用名称.views

from django.urls import path


urlpatterns = [
    # 配置应用路由
    path('hello_world', 应用名称.views.helloWorld),
]

3). 项目层面的路由配置: 在Django项目的urls.py文件中 配置路由绑定试图函数和url

这是配置项目层面的路由

urlpatterns = [
    ...
    # 配置项目
    path('映射url/', include('应用名称.urls'))
    ...
]

4). 将应用添加到Django配置文件中

INSTALLED_APPS = [
    ...
    '应用名称.apps.XXXConfig',
]

4. Django模型层

1. 什么是模型层

位于Django视图层和数据库之间, 用于将Python对象和数据库表之间的转换

模型层作用:

  • 屏蔽不同数据库之间的差异
  • 让开发者更加专注于业务逻辑的开发
  • 提供了很多便捷的工具有利于开发

2. 模型层数据库配置

在Django项目的setting.py文件中

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

修改成mysql数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库名称',
        'USER': '用户名',
        'PASSWORD': '密码',
        'HOST': '',
        'PORT': '端口号'
    }
}

3. 模型层例子

(1). 模型层定义字段

自增类型
自增类型 作用
AutoField 主键自增
BigAutoField 更大长度的主键自增
二进制和布尔类型
二进制和布尔类型 作用
BinaryField 二进制
BooleanField 布尔类型
NullBooleanField 不能为空的布尔类型
整数类型
整数类型 作用 长度
PostitiveSmallIntegerField 正整数 5字节
SmallIntegerField 整数 6字节
PostitiveIntegerField 正整数 10字节
IntegerField 整数 11字节
BigIntegerField 整数 20字节
字符和文本类型
字符和文本类型 数据库对应类型
CharField varchar
TextField longText
时间类型
时间类型 作用 数据库类型
DateField 年月日
DateTimeField 年月日时分秒
DurationField Python timedelta int类型
浮点类型
浮点类型 作用
FloatField 小数
DecimalField 小数
其他类型
其他类型 作用
EmailField 邮箱
ImageField 图片
FileField 文件
FilePathField 文件路径
URLField url路径
UUIDField uuid
GenericIPAdressField ip地址
关系类型
关系类型 作用
OneToOneField 一对一
ManyToManyField 多对多
ForeignKey 多对一或一对多

(2). 字段参数

所有字段共有参数
参数 作用 取值
db_column 指定数据库表中对应字段 str
primary_key 主键 boolean
verbose_name 备注或别名 str
unique 字段唯一 boolean
null 数据库中字段是否允许空 boolean
blank 表单提交时是否允许为空 boolean
db_index 设置索引 boolean
help_text 表单显示帮助信息 str
editable 用户是否可以更改 boolean
个别字段参数
拥有字段 参数 作用 取值
CharField max_length 指定最大长度 int
日期类型 unique_for_date 日期是否唯一 boolean
日期类型 unique_for_month 日期月份是否唯一 boolean
日期类型 unique_for_year 日期年份是否唯一 boolean
日期类型 auto_now 更新记录的时间 boolean
日期类型 auto_now_add 增加记录时的时间 boolean
DecimalField max_digits 数字个数 int
DecimalField decimal_places 小数个数 int
关系型字段参数
拥有字段 参数 作用 取值
OneToOneField related_name 外键关联的反向查询 str
ForeignKey on_delete 级联操作 指定值

models.CASCADED 级联删除

models.PROTECT 需要先删除关联数据, 才可以删除当前数据

models.SET_NULL 关联数据置空 null = True, blank = True

models.SET_DEFAULT 关联字段值为默认值

models.SET_NOTHING 啥也不做

models.SET() 传递一个值或一个函数的返回值

自关联

一个数据库中的字段关联另一个数据库中的某一字段

地址表中, 地址的字段关联地址

from django.db import models

class AddressInfo(models.Model):
    address = models.CharField(max_length=200, null=True, blank=True, verbose_name="地址")
    pid = models.ForeignKey('self', null=True, blank=True, verbose_name="自关联")
    # pid = models.ForeignKey('AddressInfo', null=True, blank=True, verbose_name="自关联")

    def __str__(self):
        return self.address

(3). 设计博客模型层

在Django应用的models.py文件中定义模型

from django.db import models


class Article(models.Model):
    # 文章Id
    articleId = models.AutoField(primary_key=True)
    # 文章标题
    title = models.TextField()
    # 文章摘要
    briefContent = models.TextField()
    # 文章内容
    content = models.TextField()
    # 文章发布日期
    publishDate = models.DateTimeField(auto_now=True)

    # admin中显示
    def __str__(self) :
        return self.title

(4). 模型迁移

python manage.py makemigrations

生成数据库要执行的内容到migrations文件夹下

python manage.py migrate

执行migrations文件夹下的文件, 并将过程记录到django_migrations数据表中(该表是django自动生成的)

python manage.py makemigrations

python manage.py migrate 

(5). 注册模型到admin

在应用的admin.py文件中配置

from django.contrib import admin

from .models import Article

admin.site.register(Article)

(6). 模型迁出

将数据库转成models

python manage.py inspectdb > models.py

模型类代码会出现在models.py文件中

(7). 模型删除

1). 删除models.py文件中的模型类代码
2). 删除模型类在migrations文件夹下的对应文件
3). 删除django_migrations表中的记录
4). 删除模型类对应的数据表

4. 初识 Django Shell

1. 什么是 Django Shell

Python Shell是用于交互式的Python编程

Django Shell是用于交互式的Django项目环境

2. 为什么使用 Django Shell

  1. 临时性操作使用Django Shell更加方便
  2. 小范围Debug更简单,不需要运行整个项目来测试

3. 使用 Django Shell

(1). 进入 Django Shell

python manage.py shell

(2). 使用Django Shell导入数据

新建文章

from testapp1.models import Article
a = Article()
a.title = 'Test Django Shell'
a.brief_content = 'Mzy'
a.content = 'Test new Article'
# 存储数据库
a.save()
# 取出全部数据
articles = Article.objects.all()
article = articles[0]

5. 初识 Django Admin

(1). 什么是 Django Admin

Django框架的后台管理工具

可以读取定义的模型元数据, 提供强大的管理使用页面

(2). 为什么使用 Django Admin

  1. 方便添加数据
  2. 管理页面

(3). 使用 Django Shell

1). 创建管理员用户

python manage.py createsuperuser

2). 登录进入管理系统

访问admin

6. 初识 Django 模板系统

模板系统的表现形式是文本

1. 基本语法

标签 作用
{{变量}} 变量标签
{% for x in list %}, {% endfor %} for循环标签
{% if %}, {% else %}, {% endif %} if-else标签
{% load static %} 使用静态文件, 自动查找static目录
{% csrf_token %} 跨域

2. 使用模板系统

在应用的views.py文件写视图

使用render返回html页面, 默认去应用的templates文件夹里找

def getIndexPage(request):
    articles = Article.objects.all()
    return render(request, 'index.html', {
        # 左边是模板变量, 右边是把值赋予的变量
        'articles': articles
    })

在应用的urls.py文件配置路由

urlpatterns = [
    # 配置应用路由
    path('hello_world', testapp1.views.helloWorld),
    path('getArticle', testapp1.views.getArticle),
    path('index', testapp1.views.getIndexPage),
    path('detail', testapp1.views.getDetailPage),
]

3. 获取url路径参数

urlpatterns = [
    path('detail/<int:articleId>', testapp1.views.getDetailPage)
]
def getDetailPage(request, articleId):
    articles = Article.objects.all()
    article = None
    for i in articles:
        if i.articleId == articleId:
            article = i
            break
    return render(request, 'detail.html', {
        'article': article
    })

6. 初识 Django ORM

(1). ORM

Object Relational Mapping

(2). 配置数据库

setting.py文件中配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'PythonTest',
        'USER': 'root',
        'PASSWORD': 'xxx',
        'HOST': 'xxx',
        'PORT': 'xxx'
    }
}

安装mysqlclient

pip install mysqlclient

安装PyMySQL

pip install PyMySQL

(3). 元数据

from django.db import models

class AddressInfo(models.Model):
    address = models.CharField(max_length=200, null=True, blank=True, verbose_name="地址")
    pid = models.ForeignKey('self', null=True, blank=True, verbose_name="自关联")
    # pid = models.ForeignKey('AddressInfo', null=True, blank=True, verbose_name="自关联")

    def __str__(self):
        return self.address
    
    class Meta:
        # 设置表名
        db_table = 'address'
        # 设置排序字段
        ordering = [
            'pid'
        ]
        # 设置表备注
        verbose_name = '地址信息'
        verbose_name_plural = verbose_name
        # 指定数据表是不是抽象的, 抽象的不生成数据表, 只用来继承
        abstract = False
        # 设置权限
        permissions = (
            ('权限', '说明'),
        )
        # 是否按照Django管理模式管理该表
        managed = True
        # 联合约束
        unique_together = (
            (), ()
        )
        # 设置模型类所属应用
        app_label = 'testapp1'
        # 定义数据库表空间
        db_tablespace = ''

(4). 实战建表

讲师信息表 课程信息表 学生信息表 助教信息表

助教和讲师是一对一

课程和讲师是多对一

学生信息和课程是多对多

讲师和课程 讲师是父表, 课程是子表

课程和学生 课程是父表, 学生是子表

讲师和助教 讲师是父表, 助教是子表

1). 讲师表

from django.db import models

class Teacher(models.Model):
    # 昵称
    nickname = models.CharField(
        max_length = 30,
        primary_key = True,
        db_index = True,
        verbose_name = "昵称"
    )
    # 个性签名
    introduction = models.TextField(
        default = "这位同学很懒, 木有签名~",
        verbose_name = "个性签名"
    )
    # 粉丝数
    fans = models.PositiveIntegerField(
        default = 0,
        verbose_name = "粉丝数"
    )
    # 用户创建时间
    createTime = models.DateTimeField(
        auto_now_add = True,
        verbose_name = "创建时间"
    )
    # 用户信息修改时间
    updateTime = models.DateTimeField(
        auto_now = True,
        verbose_name = "修改时间"
    )

    class Meta:
        verbose_name = "讲师信息表"
        verbose_name_plural = verbose_name

2). 课程表

from django.db import models

class Course(models.Model):
    """课程信息表"""
    # 课程名
    title = models.CharField(
        max_length = 100,
        primary_key = True,
        db_index = True,
        verbose_name = "课程名"
    )
    # 课程类型
    type = models.CharField(
        choices = (
            (1, "实战课"), (2, "免费课"), (3, "其他")
        ),
        max_length = 1,
        default = 0,
        verbose_name = "课程类型"
    )
    # 价格
    price = models.PositiveIntegerField(
        verbose_name = "价格"
    )
    # 销量
    volume = models.PositiveBigIntegerField(
        verbose_name = "销量"
    )
    # 上线时间
    createTime = models.DateTimeField(
        auto_now_add = True,
        verbose_name = "上线时间"
    )
    # 更新时间
    updateTime = models.DateTimeField(
        auto_now = True,
        verbose_name = "更新时间"
    )
    
        # 设置外键关联
    teacher = models.ForeignKey(
        Teacher, 
        # 删除级联
        on_delete = models.CASCADE, 
        null = True,
        blank = True,
        verbose_name = "课程讲师"
    )

    class Meta:
        verbose_name = "课程信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.get_type_display()}-{self.title}"

get_XXX_display()函数获取字段

例如, 如果如下类型字段存储的是1, 使用该函数后, 获得1所对应的值, 这里字段使用choice是数据库枚举类型

    type = models.CharField(
        choices = (
            (1, "实战课"), (2, "免费课"), (3, "其他")
        ),
        max_length = 1,
        default = 0,
        verbose_name = "课程类型"
    )

F运算符即format函数简化版, 3.6版本新加入的

原版

>>> a = "{}-{}"
>>> a.format("1", "2")
'1-2'

简化版

>>> a = 1
>>> b = 2
>>> c = f"{a}-{b}"
print(c)
1-2

f"{self.get_type_display()}-{self.title}"

相当于

"{}-{}".format(self.get_type_display(), self.title)

3). 学生信息表

from django.db import models

class Student(models.Model):
    """学生信息表"""
    # 昵称
    nickname = models.CharField(
        max_length = 30,
        primary_key = True,
        db_index = True,
        verbose_name = "昵称"
    )
    # 年龄
    age = models.PositiveSmallIntegerField(
        verbose_name = "年龄"
    )
    # 性别
    gender = models.CharField(
        choices = (
            (1, "男"), (2, "女"), (0, "保密")
        ),
        max_length = 1,
        default = 0,
        verbose_name = "性别"
    )
    # 学习时常
    fans = models.PositiveIntegerField(
        default = 0,
        verbose_name = "学习时常"
    )
    # 用户创建时间
    createTime = models.DateTimeField(
        auto_now_add = True,
        verbose_name = "创建时间"
    )
    # 用户信息修改时间
    updateTime = models.DateTimeField(
        auto_now = True,
        verbose_name = "修改时间"
    )
    
    # 设置外键关联
    course = models.ManyToManyField(
        Course,
        verbose_name = "课程"
    )

    class Meta:
        verbose_name = "学生信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.nickname

4). 助教信息表

from django.db import models

class TeacherAssistant(models.Model):
    """助教信息表"""
    # 昵称
    nickname = models.CharField(
        max_length = 30,
        primary_key = True,
        db_index = True,
        verbose_name = "昵称"
    )
    # 爱好
    hobby = models.CharField(
        max_length = 100,
        null = True,
        blank = True,
        verbose_name = "爱好"
    )
    # 用户创建时间
    createTime = models.DateTimeField(
        auto_now_add = True,
        verbose_name = "创建时间"
    )
    # 用户信息修改时间
    updateTime = models.DateTimeField(
        auto_now = True,
        verbose_name = "修改时间"
    )

    # 设置外键关联
    teacher = models.OneToOneField(
        Teacher,
        # 设置当关联的讲师被删除时, 与其关联的助教的讲师字段置为空
        on_delete = models.SET_NULL,
        null = True,
        blank = True,
        verbose_name = "讲师"
    )
    
    class Meta:
        verbose_name = "助教信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.nickname

外键字段写到子表

(5). Models API

使用objects模型类对象管理器进行查询

1). 查询全部数据

使用all()函数, 返回结果为QuerySet

模型类名.objects.all()

    teachers = Teacher.objects.all()

2). 根据指定字段的值查询

使用get()函数, 返回结果为该类

模型类名.objects.get()

    teachers = Teacher.objects.get(nickname = '惠')
    teachers = Teacher.objects.get(fans = 54, nickname = '惠')

函数的参数: 字段名 = 值 可以指定多个字段的值

3). 条件查询

使用filter()函数, 返回结果为QuerySet

模型类名.objects.filter()

函数参数(整数类型) 解释 备注
字段名__gte 大于等于
字段名__gt 大于
字段名__in 在…中 取值为一个列表、元组或集合
字段名__lt 小于
字段名__lte 小于等于
字段名__exact 等于
字段名__isnull 是不是空
字段名__range 在…中 取值为一个列表、元组或集合 (起始值, 终止值)
函数参数(字符串类型) 解释 备注
字段名__regex 是否匹配正则表达式
字段名__iregex 是否匹配正则表达式(不区分大小写)
字段名__in 在…中 取值为一个列表、元组或集合
字段名__contains 包含
字段名__icontains 包含(不区分大小写)
字段名__iexact 等于(不区分大小写)
字段名__exact 等于
字段名__isnull 是不是空
字段名__startwith 以…开头
字段名__istartwith 以…开头(不区分大小写)
字段名__endwith 以…结尾
字段名__iendtwith 以…结尾(不区分大小写)
    teachers = Teacher.objects.filter(fans__gte = 20)

4). 查看查询的sql

print(Teacher.objects.filter(fans__gte = 20).query)

5). API

函数 解释 备注
exclude() 排除满足条件的对象
annotate() 使用聚合函数
order_by() 对查询集进行排序
reverse() 反向排序
distinct() 对查询集去重
values() 返回包含对象具体值的字典的QuerySet
values_list() 与values()类似,只是返回的是元组
dates() 根据日期获取查询集
datetimes() 根据时间获取查询集
none() 创建空的查询集
union() 并集
intersection() 交集
difference() 差集
select_related() 附带查询关联对象
prefetch_related() 预先查询
extra() 附加SQL查询
defer() 不加载指定字段
only() 只加载指定的字段
using() 选择数据库
select_for_update() 锁住选择的对象,直到事务结束。
raw() 接收一个原始的SQL查询

可以使用多个参数

7. Django 请求和响应

(1). 请求

request是一个对象,封装了用户发送过来的所有请求相关数据

请求属性 解释
request.method 请求方式
request.GET 获得queryString, 类型是: django.http.request.QueryDict
request.POST 获得请求体, 类型是: django.http.request.QueryDict

1). 获取请求方法

def learnRequest(request):
    method = request.method
    print(method)
    return HttpResponse('hello world')

2). 获取GET请求的QueryString

发送请求

xxx/xxx?a=123

def learnRequest(request):
    queryString = request.GET
    # 获取a键的值
    print(queryString.get('a'))
    return HttpResponse('hello world')

没有键则返回 None

3). 获取POST请求体

def learnRequest(request):
    body = request.POST
    print(body)
    return HttpResponse('123')

(2). 响应

使用HttpResponse返回字符串

def learnResponse(request):
    return HttpResponse('123')

使用render()函数, 读取html内容, 渲染(替换)为字符串, 返回给浏览器

def learnResponse(request):
    return render(request, 'index.html', {
        'variable': 'value'
    })

使用redirect()函数重定向

def learnResponse(request):
    return redirect('https://www.baidu.com')

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122793.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!