Django(一) 模型Model知识点

使用django进行数据库开发的步骤如下:

• 1.在models.py中定义模型类
• 2.迁移
• 3.通过类和对象完成数据增删改查操作

1.定义模型类

模型类定义在models.py文件中,继承自models.Model类。

from django.db import models


# 一类
# 图书类
class BookInfo(models.Model):
    '''图书模型类'''
    # 书名
    btitle = models.CharField(max_length=20)
    # 时间
    bpub_date = models.DateField()

# 多类
# 英雄人物类
class HeroInfo(models.Model):
    '''英雄人物模型类'''
    # 英雄名称
    hname = models.CharField(max_length=20)
    # 性别
    hgender = models.BooleanField(default=False)
    # 备注
    hcomment = models.CharField(max_length=128)
    # 关系属性,建立图书类和英雄人物类一对多关系
    hbook = models.ForeignKey('BookInfo')
    
    
    # 自定义模型类对应的表名
    # class Meat:
    # 	db_table = 'bookinfo'

说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长。
BookInfo类和HeroInfo类之间具有一对多的关系,这个一对多的关系应该定义在多的那个类,也就是HeroInfo类中。

2.迁移

迁移由两步完成

# 生成迁移文件:根据模型类生成创建表的迁移文件。
python manage.py makemigrations

# 执行迁移:根据第一步生成的迁移文件在数据库中创建表。
python manage.py migrate

3.数据操作shell

python manage.py shell

# 首先引入booktest/models中的类:
from booktest.models import BookInfo,HeroInfo

# 查询所有图书信息:
BookInfo.objects.all()

# 新建图书对象:
b=BookInfo()
b.btitle="射雕英雄传"
from datetime import date
b.bpub_date=date(1991,1,31)
b.save()

字段类型

1.命名限制

1)不能是python的保留关键字。
2)不允许使用连续的下划线,这是由django的查询方式决定的。
3)定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名=models.字段类型(选项)

2.字段类型

使用时需要引入django.db.models包,字段类型如下:

类型 描述
AutoField 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性。
CharField CharField(max_length=20, verbose_name=‘名称’) 字符串。参数max_length表示最大字符个数
BooleanField BooleanField(default=False) 布尔字段,值为True或False。一般用来处理男女性别属性
DateField 日期。 1.参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。 2. 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。 3.参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。
DateTimeField 日期时间,参数同DateField
ImageField 继承于FileField,对上传的内容进行校验,确保是有效的图片(jpg、png)
TextField 大文本字段,一般超过4000个字符时使用
IntegerField 整数,它同AutoField一样,唯一的差别就是不自增
SmallIntegerField 小整数时一般会用到
FloatField 浮点数。参数同上
NullBooleanField 支持Null、True、False三种值
TimeField 时间,参数同DateField
FileField 上传文件字段。

3.选项

通过选项实现对字段的约束,选项如下:

选项名 描述
default 设置默认值
verbose_name 用于指定名称
primary_key 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
choices 配置字段的choices后,在admin页面上就可以看到对应的选项展示
unique 如果为True, 这个字段在表中必须有唯一值,默认值是False。
db_index 若值为True, 则在表中会为此字段创建索引,默认值是False。
db_column 字段的名称,如果未指定,则使用我们定义的Field对应数据库中的字段名称。
null 如果为True,表示允许为空,默认值是False。
blank 如果为True,则该字段允许为空白,默认值是False。

对比:null是数据库范畴的概念,blank是后台管理页面表单验证范畴的。
注意:当修改模型类之后,如果影响表结构,则必须重新做迁移,商品的选项中default和blank不影响表结构。

查询

QuerySet
Django中的QuerySet本质上是一个懒加载的对象,当产生数据库查询操作时,只是会返回一个QuerySet对象,等你真正用到它的时候才会执行查询(和迭代器功能很相似)。
通过模型类.objects属性可以调用如下函数,实现对模型类对应的数据表的查询

函数名 功能 返回值 说明
get 返回返回结果只有一条 返回值是一个模型类对象 参数中写查询条件 1) 如果查到多条数据,则抛异常MultipleObjectsReturned。 2)查询不到数据,则抛异常:DoesNotExist。
all 返回模型类对应表格中的所有数据。 返回值是QuerySet类型 查询集
filter 返回满足条件的所有结果 返回值是QuerySet类型 参数写查询条件。
exclude 返回不满足条件的数据。 返回值是QuerySet类型 参数写查询条件。
order_by 对查询结果进行排序。 返回值是QuerySet类型 参数中写根据哪些字段进行排序
values 返回查询对象的值 返回值是QuerySet类型 查看具体数值
first 返回queryset中匹配到的第一个对象,如果没有匹配到对象则为None,如果queryset没有定义排序,则按主键自动排序 返回值是一个模型类对象
exists 判断查询的数据是否存在,存在时返回True,否则返回False 返回值是一个布尔值
aggregate 返回模型类对应表格中的所有数据。 返回值是一个字典 使用前需先导入聚合类: from django.db.models import Sum,Count,Max,Min,Avg
count 统计满足条件数据的数目 返回值是一个数字

filter模糊查询

语法格式:
模型类属性名__条件名=值
a)判判断条件名 contains,endswith
例:查询书名包含’传’的图书 contains

BookInfo.objects.filter(btitle__contains='传')

例:查询书名以’部’结尾的图书 endswith

BookInfo.objects.filter(btitle__endswith='部')

b)空查询 isnull
例:查询书名不为空的图书。isnull

BookInfo.objects.filter(btitle__isnull=False)

c)范围查询 in
例:查询id为1或3或5的图书。

BookInfo.objects.filter(id__in = [1,3,5])

d)比较查询
大于gt
小于lt
大于等于 gte
小于等于 lte
例:查询id大于3的图书。

BookInfo.objects.filter(id__gt=3)

e)日期查询
例:查询1980年发表的图书。

BookInfo.objects.filter(bpub_date__year=1980)

例:查询1980年1月1日后发表的图书。

from datetime import date
BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))

F对象

作用:用于类属性之间的比较。
使用之前需要先导入

from django.db.models import F

例:查询图书阅读量大于评论量图书信息。

BookInfo.objects.filter(bread__gt=F('bcomment'))

例:查询图书阅读量大于2倍评论量图书信息。

BookInfo.objects.filter(bread__gt=F('bcomment')*2)

Q对象

作用:用于查询时条件之间的逻辑关系。not and or,可以对Q对象进行&|~操作。
使用之前需要先导入:

from django.db.models import Q

例:查询id大于3且阅读量大于30的图书的信息。

BookInfo.objects.filter(id__gt=3, bread__gt=30)
BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))

例:查询id大于3或者阅读量大于30的图书的信息。

BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))

例:查询id不等于3图书的信息。

BookInfo.objects.filter(~Q(id=3))

模型类关系

1.一对多关系

例:图书类-英雄类
models.ForeignKey(to=UserProfile, on_delete=models.CASCADE)
定义在多的类中。

2. 多对多关系

例:新闻类-新闻类型类 体育新闻 国际新闻
models.ManyToManyField(to='UserInfo',on_delete=models.CASCADE)
定义在哪个类中都可以。

3.一对一关系

例:员工基本信息类-员工详细信息类 员工工号
models.OneToOneField(to='UserInfo',on_delete=models.CASCADE)
定义在哪个类中都可以。

关联查询(一对多)

由一类(UserProfile)查询多类(Article)
方法一:
格式:一类的对象.多类名小写_set.all()

b = models.UserProfile.objects.get(username='admin')
b.article_set.all()

<QuerySet [<Article: 啊1>, <Article: 啦啦啦我是2>, <Article: 啦啦啦我是3>]>
方法二:多类名.objects.filter(关联属性__一类属性名__条件名)

models.Article.objects.filter(user__username='admin')
<QuerySet [<Article:1>, <Article: 啦啦啦我是2>, <Article: 啦啦啦我是3>]>

由多类(Article)查询一类(UserProfile)

多类的对象.关联属性

方法一:多类的对象.主键

h = models.Article.objects.get(title='啦啦啦我是3')
h.user

<UserProfile: admin>
方法二:一类名.objects.filter(多类名小写__多类属性名__条件名)

models.UserProfile.objects.filter(article__title='啦啦啦我是3')
<QuerySet [<UserProfile: admin>]>

自关联

自关联是一种特殊的一对多(把关联属性指向了自己)
案例:显示广州市的上级地区和下级地区
在这里插入图片描述

models.py

class AreaInfo(models.Model):
    '''地区模型类'''
    # 地区名称
    atitle = models.CharField(max_length=20)
    # 关系属性,代表当前地区的父级地区,主键指向自己,允许为空
    aParent = models.ForeignKey('self', null=True, blank=True)
views.py

from booktest.models import AreaInfo
def areas(request):
    '''获取广州市的上级地区和下级地图'''
    # 1.获取广州市信息
    area = AreaInfo.objects.get(atitle='广州市')
    # 2.查询广州市的上级地区
    parent = area.aParent
    # 3.查询广州市的下级地区
    children = area.areainfo_set.all()
    # 使用模板
    return render(request, 'booktest/areas.html', {'area':area,'parent':parent, 'children':children})
urls.py

from django.conf.urls import url
from booktest import views
urlpatterns = [
    url(r'^areas$', views.areas),
]
areas.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自关联模板</title>
</head>
<body>
<h1>当前地区</h1>
{{ area.atitle }}<br/>
<h1>父级地区</h1>
{{ parent.atitle }}<br/>
<h1>下级地区</h1>
<ul>
    {% for child in children %}
        <li>{{ child.atitle }}</li>
    {% endfor %}
</ul>
</body>
</html>

在这里插入图片描述

插入和删除

插入操作

方法一,调用模块函数对象
b = models.UserProfile()
b.username = ‘xiaoming’
b.mobile = ‘15830900798’
b.save()
方法二,直接加
models.UserProfile.objects.create(username=‘xiaohong’,mobile=15830900797)

删除操作

from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 多对多的情况下,删除 book id 为1,author id 大于0的记录
    book = models.Book.objects.filter(id=2)[0]
    authors = models.Author.objects.filter(id__gt=0)
    book.authors.remove(*authors)

    # 删除单条记录,删除 book 表中 id 为 1 的记录
    models.Book.objects.filter(id=1).delete()
    return HttpResponse("Hello world")

模型管理器

作用

objects是Django帮我自动生成的管理器对象,通过这个管理器可以实现对数据的查询。
自定义管理器之后Django不再帮我们生成默认的objects管理器。

模型类的属性

属性objects:管理器,是models.Manager类型的对象,用于与数据库进行交互。
当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,自定义管理器后,Django不再生成默认管理器objects。
为模型类BookInfo定义管理器books语法如下:

class BookInfo(models.Model):
    ...
    books = models.Manager()

管理器Manager

管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器。Django支持自定义管理器类,继承models.Manager。
自定义管理器类主要用于两种情况:
• 1.改变查询的结果集,重写all()方法
• 2.管理器类中定义一个方法帮我们操作数据表,如向数据库中插入数据。
1.在管理器类中定义创建对象的方法
对模型类对应的数据表进行操作时,推荐将这些操作数据表的方法封装起来,放到模型管理器类中。
a)打开booktest/models.py文件,定义方法create。

from django.db import models

# 编写 AddressManager 类来继承 models.Manager
class AddressManager(models.Manager):
    """地址模型管理器"""
    def get_default_address(self, user):
        """获取用户默认收货地址"""
        try:
            address = self.get(user=user, is_default=True)
        except self.model.DoesNotExist:
            address = None

        return address


class Address(BaseModel):
    '''地址模型类'''
    user = models.ForeignKey('User', verbose_name='所属账户')
    receiver = models.CharField(max_length=20, verbose_name='收件人')
    addr = models.CharField(max_length=256, verbose_name='收件地址')
    zip_code = models.CharField(max_length=6, null=True, verbose_name='邮政编码')
    phone = models.CharField(max_length=11, verbose_name='联系电话')
    is_default = models.BooleanField(default=False, verbose_name='是否默认')

    objects = AddressManager()

    class Meta:
        db_table = 'df_address'
        verbose_name = '地址'
        verbose_name_plural = verbose_name

b)调用管理器语法如下

from django.shortcuts import render
from apps.user.models import Address


class UserAddressView(View):
    """用户中心-地址页"""
    def get(self, request):
        """显示地址页"""
        # 调用管理器方法
        address = Address.objects.get_default_address(request.user)

        return render(request, 'user_center_site.html', {'page': 'address', 'address': address})

元选项

在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字。
数据表的默认名称为:

<app_name>_<model_name>
例:
booktest_bookinfo

例:指定BookInfo模型类生成的数据表名为bookinfo。
在BookInfo模型类中添加如下内容,代码如下:

#定义图书模型类BookInfo
class BookInfo(models.Model):
    ...
    #定义元选项
    class Meta:
      db_table='bookinfo' #指定BookInfo生成的数据表名为bookinfo

AbstractUser用户模型类

• User 对象基本属性:
• 创建用户必选: username、password
• 创建用户可选:email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse
• 判断用户是否通过认证:is_authenticated
• 创建用户的方法

user = UserProfile.objects.create(username=username,password=password,email=email,mobile=mobile)

• 用户认证的方法
Django 自带用户认证系统
它处理用户账号、组、权限以及基于 cookie 的用户会话
• Django 认证系统同时处理认证和授权
• 认证:验证一个用户是否它声称的那个人,可用于账号登录.
• 授权:授权决定一个通过了认证的用户被允许做什么.
• Django 认证系统包含的内容
• 用户:用户模型类、用户认证.
• 权限:标识一个用户是否可以做一个特定的任务,MIS 系统常用到.
• 组:对多个具有相同权限的用户进行统一管理,MIS 系统常用到.
• 密码:一个可配置的密码哈希系统,设置密码、密码校验.
• 处理密码的方法

加密:make_password(原文密码)
校验密码:check_password(原文密码,加密密码)

自定义用户模型类

from django.contrib.auth.models import AbstractUser
from django.db import models

class UserProfile(AbstractUser):
    mobile = models.CharField(max_length=11, verbose_name='手机号码', unique=True)
    icon = models.ImageField(upload_to='uploads/%Y/%m/&d')

    class Meta:
        db_table = 'userprofile'
        verbose_name = '用户表'
        verbose_name_plural = verbose_name

指定用户模型类
• Django 用户模型类是通过全局配置项 AUTH_USER_MODEL 决定的
又因为我们重写了用户模型类, 所以我们需要重新指定默认的用户模型类:
• 在 dev.py 文件中添加如下代码:

# 如果用户继承了AbstractUser,需要修改auth_user的模型
AUTH_USER_MODEL = 'user.UserProfile'
发布了6 篇原创文章 · 获赞 0 · 访问量 54

猜你喜欢

转载自blog.csdn.net/Hongfei_ma/article/details/104918383
今日推荐