django与用户进行交互,页面一旦关闭,或服务器重启,一切都将回到原始状态。
所以需要使用数据库对用户操作数据进行保存,Django通过自带的ORM框架操作数据库,并且原生支持轻量级的sqlite3数据库。
1.django使用mysql配置
需要安装安装数据库驱动mysqlclient
pip install mysqlclient
如果使用其他数据库,需要自己进行settings.py中进行配置。mysql的配置如下:
# DATABASES = {
# # 'default': {
# # 'ENGINE': 'django.db.backends.sqlite3',
# # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# # }
# # }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',#数据库引擎
'NAME': 'django_test',#数据库名称,需要自己手动创建,django不会主动为你创建
'USER': 'root', #数据库用户名
'PASSWORD': 'talent', #数据库密码
'HOST':'localhost', #数据库主机ip地址
'PORT':'3306', #mysql使用的端口号
}
}
2.django与mysql交互
(1)创建数据库的表类,类名代表了数据库表名,且继承了models.Model,类里面的字段代表数据表中的字段
(2)对数据库表进行同步操作,python manage.py makemigrations,python manage.py migrate
(3)使用数据库表类,进行数据库的增删改查操作。
3.字段类型-参数详解
django的models里面字段类型除了上面的常用的 models.CharField和models.IntegerField,还有更多的类型
1、models.AutoField 自增列= int(11)
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField 字符串字段
必须 max_length 参数
3、models.BooleanField 布尔类型=tinyint(1)
不能为空,Blank=True
4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
5、models.DateField 日期类型 date
对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField 日期类型 datetime
同DateField的参数
7、models.Decimal 十进制小数类型= decimal
必须指定整数位max_digits和小数位decimal_places
8、models.EmailField 字符串类型(正则表达式邮箱)=varchar
对字符串进行正则表达式
9、models.FloatField 浮点类型= double
10、models.IntegerField 整形
11、models.BigIntegerField 长整形
integer_field_ranges ={
'SmallIntegerField':(-32768,32767),
'IntegerField':(-2147483648,2147483647),
'BigIntegerField':(-9223372036854775808,9223372036854775807),
'PositiveSmallIntegerField':(0,32767),
'PositiveIntegerField':(0,2147483647),
}
12、models.IPAddressField 字符串类型(ip4正则表达式)
13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
参数protocol可以是:both、ipv4、ipv6
验证时,会根据设置报错
14、models.NullBooleanField 允许为空的布尔类型
15、models.PositiveIntegerFiel 正Integer
16、models.PositiveSmallIntegerField 正smallInteger
17、models.SlugField 减号、下划线、字母、数字
18、models.SmallIntegerField 数字
数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField 字符串=longtext
20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField 字符串,地址正则表达式
22、models.BinaryField 二进制
23、models.ImageField图片
24、models.FilePathField文件
对应的字段参数如下:
1、null=True
数据库中字段是否可以为空
2、blank=True
django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
auto_now 自动创建---无论添加或修改,都是当前操作的时间
auto_now_add 自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default 默认值
8、verbose_name Admin中字段的显示名称
9、name|db_column 数据库中的字段名称
10、unique=True 不允许重复
11、db_index = True 数据库索引
12、editable=True 在Admin里是否可编辑
13、error_messages=None 错误提示
14、auto_created=False 自动创建
15、help_text 在Admin中提示帮助信息
16、validators=[]
17、upload-to
4.实际使用
创建数据库表类,执行同步操作后,可以从数据库表中看到表新增成功了,默认多一个字段id为主键
如果要使用某个字段作为主键,只需要增加字段参数primary_key =True
1.新增hero数据表类
class Hero(models.Model):
name = models.CharField(max_length=30)
propertys = models.CharField(max_length=30)
is_male = models.BooleanField(null=False)
power = models.IntegerField(default=1)
2.添加url规则
url(r'hero',views.hero),
3.templates文件hero.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hero页面</title>
</head>
<body>
<h1>用户输入:</h1>
<form action="/hero/" method="post">
英雄 名:<input type="text" name="name"/><br/>
英雄属性:<input type="text" name="propertys"/><br/>
是否男性:<input type="text" name="is_male"/><br/>
武力 值:<input type="text" name="power"/><br/>
<input type="submit" value="提交"/>
</form>
<h1>英雄展示:</h1>
<table border="1">
<thead>
<tr>英雄名</tr>
<tr>英雄属性</tr>
<tr>是否男性</tr>
<tr>武力值</tr>
</thead>
<tbody>
{% for item in data %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.propertys }}</td>
<td>{{ item.is_male}}</td>
<td>{{ item.power }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
4.视图函数:
def hero(request):
if request.method == 'POST':
name = request.POST.get('name')
propertys = request.POST.get('propertys')
is_male = request.POST.get('is_male')
power = request.POST.get('power')
print(name, propertys, is_male, power, type(name))
hero = Hero(name=name, propertys=propertys, is_male=is_male, power=power)
hero.save()
data = Hero.objects.all()
return render_to_response('hero.html', {'data': data})
实现效果:访问http://127.0.0.1:8000/hero/,
如果数据库中有数据就从,数据库中取出全部数据,展示在下方table中,上方可以通过表单提交方式,不断向数据库中提交数据
1.新增数据方法
创建数据表实例,如
hero = Hero(name=name, propertys=propertys, is_male=is_male, power=power),调用hero.save()方法
注意:创建实例时参数必须写成关键字参数形式,不可写成hero = Hero(name,propertys,is_male,power)形式,django会解析错误
2.删除数据
def delete_data(request):
#根据属性获取数据,调用delete()方法删除
# hero1 = Hero.objects.get(name = '2')
# hero1.delete()
Hero.objects.filter(id=12).delete()
# Hero.objects.all().delete()#删除所有数据
return HttpResponse("删除数据成功!!")
3.修改数据
def update_data(request):
# 1.根据属性查询到数据后,对属性进行修改,然后调用save方法保存
hero = Hero.objects.get(name='提莫')
hero.power = 100
hero.save()
# 2.根据属性查询到数据后,直接调用update()方法
Hero.objects.filter(name="德玛").update(name='诺克萨斯')
# 3.调用all方法的update方法
Hero.objects.all().update(is_male=False)
return HttpResponse("修改成功")
4.查询数据
def qury_data(request):
# get方法查询可以传递多个参数进行限制,查询结果只能是一个,限制条件如果不唯一,会报错
hero = Hero.objects.get(name='提莫')#返回是一个实例对象,<class 'hello.models.Hero'>
print(type(hero))
power_qury = Hero.objects.filter(name='德玛', is_male=False)#根据条件过滤,可返回多个
print(type(power_qury))#<class 'django.db.models.query.QuerySet'>
power = power_qury[0].power
all_hero = Hero.objects.all()#查询所有
for i in all_hero:
print(i.name)
order_by = Hero.objects.order_by("name")
for i in order_by:
print(i.name)
#查询结果可以进行切片操作Hero.objects.order_by("name")[0:2],相当于limit 2
return HttpResponse("<h1>%s</h1>" % power)
5.查询方法详解
查询方法有很多,根据返回结果分类
- 返回对象是对象列表的: all(), filter(), exclude(), order_by(), reverse(), values(), values_list(), distinct()
- 返回结果是对象: get(), first(), last()
- 返回结果是布尔值: exists()
- 返回数字: count()
返回对象列表即queryset序列,可以通过for循环进行获取每一个对象,然后使用对象调用对应的属性。也可以通过下标取某个对象,然后调用对应的属性。使用切片操作也可以获取其中某几个对象。
返回对象的可以直接调用对应的属性和方法。
values函数,可以由queryset序列调用values函数,返回值是一个字典
result=Hero.objects.all().values("name","power")
for r in result:
print(r)
返回结果:
{'name': '诺克萨斯', 'power': 10}
{'name': '剑圣', 'power': 20}
{'name': '诺克萨斯', 'power': 20}
{'name': '提莫', 'power': 100}
exclude() 它包含了与所给筛选条件不匹配的对象 调用者:objects管理器 返回queryset
result2 = Hero.objects.exclude(name = "诺克萨斯")
for r in result2:
print(r.name)
返回的是name不等于诺克萨斯的对象集合
剑圣
提莫
order_by() 对查询结果排序 由queryset对象调用,返回值是queryset,默认升序,前面加个-是代表降序
ret=Hero.objects.all().order_by("-power")
根据power值降序排列
reverse() 对查询结果反向排序 由queryset对象调用,返回值是queryset
ret=Hero.objects.all().order_by("-power").reverse()
values_list() 由queryset对象调用, 返回值是queryset 一个元组序列
ret=Hero.objects.all().values_list("name", "power")
distinct() 从返回结果中剔除重复纪录 由queryset对象调用,返回值是queryset
ret=Hero.objects.all().values("name", "power").distinct()
first(),last()方法: 返回第一条记录和返回最后一条记录 调用者:queryset 返回model对象
fir = Hero.objects.all().order_by("name").first()
exists() 如果QuerySet包含数据,就返回True,否则返回False 由queryset对象调用 返回值布尔值
is_exist=Hero.objects.all().exists()
count : 数数 由queryset对象调用 返回int
et=Hero.objects.all().count()