Python的Django框架-数据库查询(增删改查)

创建项目

django-admin startproject django_model

创建应用

python manage.py startapp model

  • 配置应用 model, 编辑 django_model/settings.py 文件:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'model',
]
  • 配置Mysql数据库:编辑 django_model/settings.py 文件, 内容如下:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # mysql数据库引擎
        'NAME': 'my_model',  # 数据库名字
        'USER': 'root',  # 用户名
        'PASSWORD': 'fe_cow',  # 密码
        'HOST': 'localhost',  # 主机
        'PORT': '3306'  # 端口
    }
}
  • 创建应用所需数据库表, 首先我们创建数据库:

    create dababase my_model charset = utf8;

  • 注意: 使用PyMysql数据库驱动,需要在 djangomodel/_init__.py 中增加如下代码:(python2不需要配置这项)

    import pymysql
    pymysql.install_as_MySQLdb()

定义模型

  • 定义模型其实就是定义一个python类;一个模型类代表数据库中一张表,一个模型类的实例代表这个数据库表中的一条特定的记录
from django.db import models

class Publisher(models.Model):
    """出版社"""
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    country = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name


class Author(models.Model):
    """作家"""
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)


class Book(models.Model):
    """书"""
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author) # 书和作者是多对多的关系
    publisher = models.ForeignKey(Publisher) # 书和出版者是多对一的关系
    publication_date = models.DateField()

    def __unicode__(self):
        return self.title
  • 定义完模型后,要执行数据库迁移操作:

    先执行python manage.py makemigrations 在执行:python manage.py migrate

  • 一张表中定义了多对多的关系,ORM会自动创建实现多对多关系的第三张表。

数据库的操作

  • 通过python shell 来演示数据库的操作。在终端切换到项目根目录下,输入命令python manage.py shell 进入shell操作环境。
增删改查
1 创建记录

方法一:实例化(调用save()方法之前,Django不会访问数据库;save()方法没有返回值)

>>> from apps.models import Author
>>> author = Author(last_name='fe_cow')
>>> author.save()
>>> print author
 fe_cow

方法二:create() (只用一条语句创建并保存一个对象,使用create()方法。)

>>> Author.objects.create(first_name='fe',last_name='cow', email='280773872@qq.com')

方法三:get_or_create(), 这种方法可以防止重复(速度稍慢,因为会先查数据库), 它返回一个元组。创建成功返回True,失败的话False,不执行创建。

>>> author = Author.objects.get_or_create(last_name='fe_cow')
>>> print author
(<Author:  fe_cow>, False)  # False:说明已经重复 创建失败
>>> author = Author.objects.get_or_create(last_name='cu_cow')
>>> print author
(<Author:  cu_cow>, True)  # True: 创建成功
2 查询记录

方法一:查询所有对象 (all()方法返回包含数据库中所有对象的一个查询集。)

>>> author = Author.objects.all()
>>> print author
<QuerySet [<Author:  fecow>, <Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>

方法二:过滤查询 (filter()返回一个新的查询集,它包含满足查询参数的对象。)

>>> author = Author.objects.filter(last_name='cu_cow')
>>> print author
<QuerySet [<Author:  cu_cow>]>

方法三:指定查询 (get查询只能返回一个对象,多了少了都会引发DoesNotExist 异常)

>>> author = Author.objects.get(id=1)
>>> print author
 fecow

方法四:双下划线查询____contains:包含;__icontains不区分大小写;__regex:正则查询;__lt:小于xxx;__lte:小于等于xxx;__gt:大于xxx;__gte:大于等于xxx;__startswith(): 以xxx开头,;__istartswith():不区分大小写以xxx开头, __endswith():以xxx结尾;__iendswith():以xxx结尾不区分大小写

  • 以上使用方法基本上都一致:对象.objects.filter(属性 __xxx) 例子如下:
>>> author = Author.objects.filter(id__gte=2)
>>> print author
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>
  • 单独说一个特殊的__in 判断字段在列表内。通常用pk指主键,不限于id,适用更好。
>>> author_list = Author.objects.values_list('id', flat=True)
# 返回的是:<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
>>> Author.objects.filter(pk__in=author)
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>

方法五:first(), last()获取查询结果中单个对象

>>> Author.objects.filter(id__gte=2)
# 返回结果:QuerySet集合
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>
>>> Author.objects.filter(id__gte=2).first()
# 返回结果:objects对象  而且返回第一个对象
<Author:  fe_cow>
>>> Author.objects.filter(id__gte=2).last()
<Author:  cu_cow>
# 返回结果:objects对象 而且返回的是最后一个对象

方法六:通过values查询

  • values('字段')用字典形式,返回的是指定字段的查询结果;
>>> Author.objects.values('last_name')
<QuerySet [{'last_name': u'fecow'}, {'last_name': u'fe_cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cu_cow'}]>
# 返回字典列表;多个字段间以逗号分隔
  • values_list('字典'),返回的也是指定字段的查询结果
>>> Author.objects.values_list('last_name')
<QuerySet [(u'fecow',), (u'fe_cow',), (u'cow',), (u'cow',), (u'cow',), (u'cow',), (u'cu_cow',)]>
# 返回的是元组列表,多个字段也是用逗号分割
  • values_list('字段', flat=True) flat=True :之后返回的是值列表
>>> Author.objects.values_list('id', flat=True)
<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
# 返回的是列表

方法六:exclude(**kwargs)反向过滤

>>> Author.objects.exclude(id__gt=2)
<QuerySet [<Author:  fecow>, <Author:  fe_cow>]>
# 取反

方法七:exists()

>>> Author.objects.filter(id=2).exists()
True
#  QuerySet包含数据返回True
>>> Author.objects.filter(last_name='Au_cow').exists()
False
#  QuerySet不包含数据返回False
3 修改记录

方法一:QuerySet.update('字段'='修改的值')

>>> Author.objects.filter(last_name='cu_cow').update(last_name='Ai_cow')
1L
# 修改的前提是先查找,然后调用update(field=val)方法,只有QuerySet集合对象才能调用该方法,也就是说通过get(), first(), last()获取的对象没有该方法。

方法二:对象赋值

>>> author_obj = Author.objects.filter(last_name='fe_cow').first()
>>> author_obj.last_name = 'Fe_cow'
>>> author_obj.save()
# 不推荐使用,效率低
4 删除记录

调用delete()方法 delete()方法支持QuerySet集合对象的删除,也支持单个对象的删除。

>>> Author.objects.filter(last_name='fe_cow').delete()
(1L, {u'apps.Book_authors': 0L, u'apps.Author': 1L})
# 默认就是级联删除,对应多对多的表也会删除

QuerySet

  • 通过名字我们也能想到从数据库查出来的结果一般是一个集合,哪怕只有一个对象,也叫集合。
QuerySet特性
  • 可以进行切片,也可以进行遍历。
>>> Author.objects.filter(id__gt=2)[:2]  # 使用切片来获取
# <QuerySet [<Author: fe cow>, <Author: fe cow>]>
>>> authors = Author.objects.filter(id__gt=2)  # 使用for循环来获取
>>> for author in authors:
...     print author 
# 打印结果如下
# fe cow 
# fe cow
# fe cow
# fe cow
  • 惰性机制: 只有使用QuerySet时,才会走数据库。像.all() filter()时,并不会真正执行数据库查询,只是翻译了SQL语句;当我们执行if xxx ,print xxx; for xxx in xxx:这些操作才会执行SQL语句,进行数据库查询。
  • 缓存机制:每次执行了数据库查询后,会将结果放在QuerySet的缓存中,下次在使用QuerySet时, 不会走数据库,直接从缓存中拿取数据。比如:
>>> author = Author.objects.all()  # 获取所有Author QuerySet中的 last_name
>>> for res in author:
...     print res.last_name  # Ai_cow  cow

>>> Author.objects.create(last_name='COW',first_name='FE')  # 接下来往数据库中插入一跳数据
>>>for res in author:
        print res.last_name  # Ai_cow  cow   # 发现,已经创建了新的数据,但是表里面没有这条数据
# 以上结果证明了QuerySet缓存的机制,新添加一条记录;打印结果没有发生改变,说明他不会重新走数据库,而是从缓存中获取数据。
>>> author = Author.objects.all()  # 获取所有Author QuerySet中的 last_name
>>> for res in author:
...     print res.last_name  # Ai_cow  cow COW
  • 12
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Python可以通过许多不同的方式与数据库进行交互,包括使用原生的Python DB API,或者使用ORM框架,比如Django或SQLAlchemy等等。这里简单介绍一下Python数据库进行增删的基本操作。 1. 连接数据库 使用Python DB API,需要先连接到数据库。连接数据库的方式因不同数据库而异,例如MySQL可以使用PyMySQL,SQLite可以使用sqlite3,PostgreSQL可以使用psycopg2等等。以下是一个MySQL连接示例: ```python import pymysql conn = pymysql.connect( host='localhost', user='root', password='password', db='database_name', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor ) ``` 2. 插入数据 插入数据需要使用SQL的INSERT语句。以下是一个MySQL插入数据的示例: ```python with conn.cursor() as cursor: sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)" cursor.execute(sql, ('[email protected]', 'password123')) conn.commit() ``` 3. 查询数据 查询数据需要使用SQL的SELECT语句。以下是一个MySQL查询数据的示例: ```python with conn.cursor() as cursor: sql = "SELECT * FROM `users` WHERE `email`=%s" cursor.execute(sql, ('[email protected]',)) result = cursor.fetchone() print(result) ``` 4. 更新数据 更新数据需要使用SQL的UPDATE语句。以下是一个MySQL更新数据的示例: ```python with conn.cursor() as cursor: sql = "UPDATE `users` SET `password`=%s WHERE `email`=%s" cursor.execute(sql, ('newpassword123', '[email protected]')) conn.commit() ``` 5. 删除数据 删除数据需要使用SQL的DELETE语句。以下是一个MySQL删除数据的示例: ```python with conn.cursor() as cursor: sql = "DELETE FROM `users` WHERE `email`=%s" cursor.execute(sql, ('[email protected]',)) conn.commit() ``` 注意:这只是一个简单的示例,实际情况中需要根据不同的数据库和数据表进行相应的修

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值