Django对各种数据库提供了很好的支持,包括PostgreSQL,MySQL,SQLite和Oracle,而且为这些数据库提供了统一的调用API,这些API统称为ORM框架。通过使用Django内置的ORM框架可以实现数据库连接和读写操作
本文以MySQL为例。
1. 配置目标数据库
在settings.py中设置数据库信息 (前提是先安装MySQL,然后创建django_db数据库)
DATABASES = {
'default': {
'ENGINE':'django.db.backends.mysql',
'NAME':'django_db', #数据库名称
'USER':'root', #数据库的用户名
'PASSWORD':'数据库密码',
'PORT':'3306'
},
}
2. 构建虚拟数据库
在App(此文中是index)的models.py文件中以类的形式定义模型。因为Django对模型和目标数据库之间有自己的映射规则,所以只能通过模型创建。如果自己直接建表,可能不一定符合Django的建表规则,导致模型与数据库之间无法建立通信联系。
#model.py
class Product(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=50)
type = models.CharField(max_length=20)
- 模型以类的形式定义,并且继承Django的models.Model类。
- 上述代码将Product类与数据表Product构成映射关系。
3.通过模型在目标数据库中创建相应的数据表
建表通过manage.py完成。
- 首先,根据models.py生成相关的.py文件,该文件用于创建数据表
python manage.py makemigrations
makemigrations 指令将models.py的内容生成数据表的脚本代码。
执行完上述代码,在migrations文件夹下,会生成一个xxxx_initial.py文件。
0001_initial.py
- 然后,使用migrate指令,根据生成脚本代码(0001_initial.py )创建数据表
python manage.py migrate
执行完上述语句,在数据库中会生成index_product表,对应模型Product。同时还默认创建多个数据表。除了index_product表外,其余表都是Django内置的功能生成的,主要用于Admin站点、用户认证和Session会话功能
Operations to perform:
Apply all migrations: admin, auth, contenttypes, index, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying index.0001_initial... OK
Applying sessions.0001_initial... OK
用数据库可视化工具查看数据库中创建的表:
数据库中创建的数据表.png
4.插入数据
为方便查看,使用shell模式,在Pycharm的Terminal下开启Shell:
python manage.py shell
- 方式一
In [6]: from index.models import *
In [7]: p = Product()
In [8]: p.id = 8
In [9]: p.name = 'nova 5'
In [10]: p.type = '手机'
In [11]: p.save()
- 方式二
In [12]: Product.objects.create(id = 9,name = 'nova 8',type = '手机')
Out[12]: <Product: Product object (9)>
- 方式三
In [13]: p = Product(id = 10,name = '荣耀10',type = '手机')
In [14]: p.save()
前面7条数据通过可视化工具DBeaver添加的,后面3条是通过上面代码添加的
5.更新数据
Product.objects.filter(name='荣耀').update(name='荣耀8')
先用filter设置条件,然后用update更新。上述例子将name='荣耀'的记录更新为name='荣耀8'。如果全表更新,则不需要使用filter,直接使用update。
6.删除数据
#删除1条数据
In [22]: Product.objects.get(id=10).delete()
Out[22]: (1, {'index.Product': 1})
#删除多条数据
In [24]: Product.objects.filter(name__startswith='nova').delete()
Out[24]: (2, {'index.Product': 2})
-
查询条件get:查询字段必须是主键或唯一约束的字段,并且查询数据必须存在,如果查询重复或不存在,会抛出异常。
-
查询条件filter:查询字段没有限制,只要是数据表的某一字段即可。查询结果以列表形式返回,如果查询为空,返回空列表。
-
filter的模糊查询
filter(要查的字段__指令= "过滤的内容")
#指令
__exact 精确等于 like ‘aaa’
__iexact 精确等于 忽略大小写 ilike ‘aaa’
__contains 包含 like ‘%aaa%’
__icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以…开头
__istartswith 以…开头 忽略大小写
__endswith 以…结尾
__iendswith 以…结尾,忽略大小写
__range 在…范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别
————————————————
filter中的 可以用Q将 and or not 联系起来。 and操作可以不用Q
from django.db.models import Q
Product.objects.filter(Q(name='畅玩') & Q(type='手机'))
等价于:
Product.objects.filter(name='畅玩',type='手机')
#or 操作
Product.objects.filter(Q(name='畅玩') | Q(name='荣耀8'))
7.读取数据并显示
在views.py中读取数据并将数据传入模板:
>def index(request):
#通过Django内置的ORM框架,查询product数据表
type_list = Product.objects.values('type').distinct()
name_list = Product.objects.values('name','type')
context = {'title':'首页','type_list':type_list,'name_list':name_list}
return render(request,'index.html',context=context,status=200)
在模板index.html显示:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
</head>
<body>
<ul id="cate_box" class="lf">
{% for type in type_list %}
<li>
<h3><a href="#">{{type.type}}</a> </h3>
<p>
{% for name in name_list %}
{% if name.type == type.type %}
<span>{{name.name}}</span>
{% endif %}
{% endfor %}
</p>
</li>
{% endfor %}
</ul>
</body>
</html>
运行之后显示的结果为:
index.html效果图
网友评论