Django-模型

本文详细介绍了如何配置Django连接MySQL数据库,对象关系映射(ORM)的基本概念、字段类型与选项,模型定义、迁移和使用方法,包括增删查改、查询过滤、统计分析和分组查询。同时涵盖了字符集设置和模型继承等内容。
摘要由CSDN通过智能技术生成

一、数据库配置

安装mysql的数据库驱动pysqlclient

pip install mysqlclient

在settings中将DATAVBASES修改为

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_test',  # 数据库名称
        'HOST': '127.0.0.1',  # 服务器地址
        'USER': 'root',  # 用户名
        'PASSWORD': '123',  # 密码
        'PORT': 3306  # 端口
    }
}

这样我们就连上了我们的数据库。

二、ORM

对象关系映射(Oject Relational Mapping,简称ORM)模式是⼀种为了解决⾯向 对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使⽤描 述对象和数据库之间映射的元数据,⾃动⽣成sql语句,将程序中的对象⾃动保存 到关系数据库中。

优点: 隐藏了数据库访问的细节,简化了sql的使⽤,提⾼了开发效率解耦业务逻辑层(view)和数据处理层(model),简化了开发流程,提⾼了系统的可移植性 提⾼了安全性

缺点: 执⾏效率低对复杂sql⽆能为⼒增加了学习成本

2.1、基本概念
面向对象面向关系
对象记录(一行)
属性字段(属性、列)

⼀个模型类对应⼀个表

2.1.1、字段类型
字段名称字段说明参数
AutoField⼀个根据实际Id⾃动增⻓的 IntegerField(通常不指定⾃动⽣成)
CharField字符串,默认的表单样式是 TextInputmax_length=字符⻓度
TextField大文本字段max_digits总位数 decimal_places⼩数位数
IntegerField整数
DecimalField使⽤python的Decimal实例的十进制浮点数
FloatField使⽤python的Float实例的十进制浮点数
BooleanFieldtrue/false 字段,此字段的默认 表单控制是CheckboxInput
NullBooleanField支持null,true,false
DateField使用python的datetime.date实 例表示的⽇期,该字段默认对 应的表单控件是⼀个TextInputauto_now和 auto_now_add、 default这三个参数不能共存
TimeField使⽤Python的datetime.time实 例表示的时间参数同DateField
DateTimeField使⽤Python的 datetime.datetime实例表示的⽇期和时间参数同DateField
ImageField继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
2.2.2、字段选项
可选参数说明
null如果True ,Django将 NULL 在数据库中存储空值。默认是 False 。不要在字符串字段上使⽤。null是数据库范畴的概念。
blank如果 True ,该字段允许为空。默认是False 。同null不同,如果字段有 blank=True ,则表单验证将允许输⼊空值。如果字段有 blank=False ,则需要该字段。
db_column⽤于此字段的数据库列的名称。如果没有给出,Django将使 ⽤该字段的名称。
db_index如果True,将为此字段创建数据库常规索引。
unique如果True,该字段在整个表格中必须是唯⼀的。
primary_key如果True,此字段是模型的主键。
default默认值,当前字段如果不给值则执⾏默认值
2.2、定义模型
from django.db import models
class 模型名(models.Model):
    属性名 = models.字段名(字段选项/参数)
    class Meta: #可选,任何⾮字段的设置可以写到Meta中
        db_table = 'user' #指定表名为user

如果没有指定主键,Django将⾃动给表创建⼀个自增长主键

id = models.AutoField(primary_key=True)
2.3、激活模型
python manage.py makemigrations #检测App下models.py的变化,记录下变更记录
python manage.py migrate #迁移,将变更记录同步到数据库中
2.4、数据库导入模型

实际上我们经常是先创建数据库再导入模型

python manage.py inspectdb > app/models.py
2.5、一个例子
from django.db import models
class User(models.Model):
    # 字段名不能是关键字
    # 不能使用连续的下划线
    '''
    常用字段:
    AutoField 一个根据实际id自动增长的integerField整型
    CharField 字符串 max_length 规定最大长度
    TextField 大文本字段,一般超过4000使用
    IntegerField 整型
    DecimalField 实数 max_digits规定总位数,decimal_places小数位数
    FloatField 浮点数
    BooleanField 布尔值 支持Ture False
    NullBooleanField 布尔值 支持Ture False Null
    DateField 时间值 三个参数auto_now,auto_now_add,default不能共存
    TimeField 同DateField
    DateTimeField 同DateField
    
    常用参数
    null 如果为Ture,则将null在数据库中储存为空
    blank 如果为Ture,该字段允许为空
    db_column 该字段的名称
    unique 如果为Ture,该字段在表中唯一
    primary_key 如果为ture,该字段为模型主键
    default 默认值 当前字段如果不给值则执行默认值
    '''

    # 继承自models,确定类型,括号内是限制
    uid = models.AutoField(primary_key = True)
    # CharField必须指明长度
    username = models.CharField(max_length=30,unique=True)
    password = models.CharField(max_length=30,unique=True)
    regtime = models.DateTimeField(auto_now_add=True)
    
    class Meta: # 元数据,模型本身的信息
        # 默认表名 应用名_模型名,这个参数可以修改默认表名
        db_table = 'user'
        # 当设置成Ture时,这个类不会生成表,而是生成一个抽象类,以供继承
        abstract = False
        # 排序
        ordering = ['username']

三、模型的使用

3.1、增删查改
def sql(request):
    # 创建
    user = User(username='tom',password='123')
    user.save()
    # 便利方法创建
    user = {'username':'tom','password':'3334'}
    User.objects.create(**user)
    # 批量创建
    User.objects.bulk_create([User(username='em',password='1232312'),User(username='e',password='123')])
    # 修改
    user = User.objects.get(username='tom')
    user.password = '333'
    user.save()
    # 删除
    user = User.objects.get(username='tom')
    user.delete()

    return HttpResponse("删改")

逻辑删除:不真的删除,但是查询的时候不再查询,增加一个is_delete字段即可实现,一般企业数据都会采取这种删除方法

3.2、Query过滤器
def query(request):
    # all过滤器 查询所有数据
    users = User.objects.all()
    print(users)

    # filter过滤器 where
    # uid = 5
    users = User.objects.filter(uid=316)
    print(users)
    # uid >= 5
    users = User.objects.filter(uid__gt=316)
    print(users)
    # 可以多次调用 326 >= uid >= 316
    users = User.objects.filter(uid__gt=316).filter(uid__lt=326)
    print(users)
    
    # 排序 按照username升序排列
    data = User.objects.order_by('username')
    for user in data:
        print(user.username)
    # 限制结果集,不能用负下标
    # 限制结果集,切片取前两条记录
    data = User.objects.order_by('username')[:2]
    # 限制结果集,切片取4,5,6,7,8,9条记录
    data = User.objects.order_by('uid')[4:9]
    
    # 取指定字段,返回一个字典
    data = User.objects.all().values('username')
    
    # 去除重复记录distinct
    data = User.objects.all().values('username').distinct()[:10]
    
    # 反序
    data = User.objects.order_by('username').reverse()
    
3.3、字段查询,非过滤器查询
user = User.objects.get(username='tom')
# 返回一个模型对象,最新的一条记录和最后的一条记录
user = User.object.first()
user = User.object.last()
# 查询结果集
num = User.object.filter(uid__lt=10)
# 判断结果集是否为空,返回Ture或者False
flag = User.object.all().exists()
num = User.object.filter(uid__lt=10)
print(flag)
3.4、字段插叙
filter
'''
>=  uid__gte=2
>   uid__gt=2
<   uid__lt=2
<=  uid__lte=2
==  uid=2 
'''
# 集合运算
date = User.object.filter(uid__in=[1,2,3,4])
# 判断空
date = User.object.filter(uid__isnull=Ture)

# 字符串操作
# startswith 以。。开头
# endswith 以。。结尾
date = User.object.filter(username__startswith='张')
date = User.object.filter(username__endswith='张')
# contains 包含
date = User.object.filter(username__contains='张')
# regex 正则匹配
date = User.object.filter(username__regex='^\w+')
# 日期查询
date = User.object.filter(regtime="2020-10-01")
date = User.object.filter(regtime__year=2020)
date = User.object.filter(regtime__month=10)
date = User.object.filter(regtime__day=1)
3.5、统计查询

首先导入一些包

from django.db.models import Max,Min,Avg,Sum,Count

使用,这里以max为例,其他的也一样

def index(request):
    uid = User.objects.aggregate(Max('uid'))
    print(uid)
    uid = User.objects.aggregate(Max('uid')).get('uid__max')
    print(uid)    
3.6、分组查询
def index(request):
    # 分组字段sex 统计字段uid
    deta = User.objects.values('sex').annotate(Count('uid'))
    print(deta)
    # 可以继续过滤
    deta = User.objects.values('sex').annotate(Count('uid')).filter(sex=1)
    print(deta)
3.7、Q对象和F对象
from django.db.models import Q,F
# Q对象:构造逻辑或逻辑非
# 查询uid>30或者sex=1
deta = User.objects.filter(Q(uid__gt=30)|Q(sex=1))
deta = User.objects.filter(~Q(sex=1))

# F对象 用于比较表中的两个字段
# 把sex堪称User的一个列名,两列值相等的时候输出
date = User.objects.filter(uid=F('sex'))
3.8、原生SQL
tmp = imput('用户名')
user = User.objects.raw("    ")#这个里面写原生的SQL语句
3.9、模型的继承

需要定义,如果父类是抽象的,子类会继承父类所有的表,但如果不是,则不会继承

class Meta:
	abstract = Ture

四、字符集

为了能够正常显示中⽂,必须把数据库的字符集设置为utf8

mysql> show variables like 'character%'; #查看字符集
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |需要修改
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |需要修改
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
修改mysql的配置⽂件
cd /etc/mysql/mysql.conf.d
sudo cp mysql.cnf mysql.cnf.bak
sudo vim mysql.cnf
在[mysqld]下增加⼀句:
character_set_server = utf8
保存并重启服务
sudo systemctl restart mysql.service #重启服务
Django自带的django-cities和django-countries是两个非常有用的插件,可以帮助您实现国家地区选择功能。 django-countries是一个包含所有国家和地区信息的插件,可以帮助您实现国家和地区选择功能。使用django-countries,您可以轻松地获取国家和地区的信息,例如国家名称、国旗、货币等等。此外,django-countries还支持多种语言,可以帮助您实现多语言的国家地区选择功能。 django-cities是一个包含世界各地城市信息的插件,可以帮助您实现省份和城市选择功能。使用django-cities,您可以轻松地获取城市的信息,例如城市名称、所属省份、经纬度等等。此外,django-cities还支持模糊查询和多语言功能,可以帮助您实现更加灵活和便捷的省份和城市选择功能。 在使用这两个插件时,您需要在Django的settings.py文件中进行配置,例如: ```python INSTALLED_APPS = [ # ... 'django_countries', 'cities', # ... ] ``` 然后可以在模型中引入这些插件提供的模型类,例如: ```python from django_countries.fields import CountryField from cities.models import City, Country class UserProfile(models.Model): # ... country = CountryField() city = models.ForeignKey(City, on_delete=models.PROTECT) # ... ``` 这样就可以在用户资料中添加国家和城市信息,并且可以使用插件提供的模板标签和表单字段来实现国家地区选择功能。 希望这些信息能够对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值