美文网首页
django模型(数据库)

django模型(数据库)

作者: 高阳刘 | 来源:发表于2017-10-18 10:58 被阅读0次

Django模型是与数据库相关的,与数据库相关的代码一般写在models.py中,Django支持sqlite3,MySQL,PostgreSQL等数据库,只需要在settings.py中配置即可,不用更改models.py中的代码,丰富的API极大的方便了使用。

1、新建项目和应用
django-admin.py startproject learn_models # 新建一个项目
cd learn_models/  # 进入到该项目的文件夹
ls  # 查看该文件下内容
# learn_models  manage.py
python manage.py startapp people  # 新建一个people应用(app)
ls  # 查看该文件下内容
# learn_models  manage.py  people

补充:新建app也可以用python manage.py startapp people,需要指出的是,django-admin.py是安装Django后多出的一条命令,并不是运行的当前目录下的django-admin.py(当前目录下去也没有),但创建项目会生成一个manage.py文件

那么project和app有什么关系呢?
一个项目一般会有多个应用,一个应用也可以用在多个项目中。

2、添加应用

建工我们新建的应用(people)添加到settings.py中的INSTALLED_APPS中,也就是告诉Django有这么一个应用。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'people',
]
# 备注: 这一步是干什么呢? 新建的 app 如果不加到 INSTALL_APPS 中的话,django 就不能自动找到app中的模板
文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件) , 后面你会学习到它们分别用来
干什么.
3、修改models.py

我们打开people/models.py文件,修改其中的代码如下:

from django.db import models
# Create your models here.

class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
# 我们新建了一个Person类,继承自models.Model,一个人有姓名和年龄
4、创建数据表

我们来同步以下数据库(我们是用默认的数据库SQLite3,无需配置)

python manage.py makemigrations
# 显示内容如下
# Migrations for 'people':
  # people/migrations/0001_initial.py
   # - Create model Person

python manage.py migrate
# 显示内容如下:
# Operations to perform:
  # Apply all migrations: admin, auth, contenttypes, people, 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 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 people.0001_initial... OK
  # Applying sessions.0001_initial... OK
# 我们会看到,Django生成了一系列的表,也生成了我们新建的people_person这个表,那么如何使用这个表呢?
5、使用Django提供的QuerySet API

Django提供了丰富的API,下面演示如何使用它。

python manage.py shell  # 在其中可以执行 Model 类的方法,向数据库中插入/更新数据等一系列操作。
# Python 3.4.3 (default, Aug 25 2017, 11:42:22) 
# Type 'copyright', 'credits' or 'license' for more information
# IPython 6.2.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from people.models import Person  # 引入models中的Person这个类
In [2]: Person.objects.create(name='liu', age='12')  # 新建一个用户liu,那么如何从数据库中查询到他呢?
Out[2]: <Person: Person object>
n [3]: Person.objects.get(name='liu')
Out[3]: <Person: Person object>
In [4]: 
# 我们用了一个.objects.get()方法查询出复合体爱建的对象,但是大家注意,查询姐结果中显示<Person: Person object>,这里并没有显示出与liu的相关信息,如果用户多了就无法知道查询出来的到底是谁,查询结果是否正确,我们重新修改以下people/models.py

name和age等字段中不能有__(双下划线,因为在Django QuerySet API中有特殊含义,用于关系,包含,不区分大小写,以什么开头或结尾,日期的大于小于,正则等)

也不鞥有python中的关键字,name是合法的,student_name也是合法的,但是student__name不合法,try,class,continue也不合法,因为他们是python的关键字(import keyword;print(keyword.kwlist)可以打出所有的关键字)

from django.db import models
# Create your models here.

class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    # 重写name字段
    def __str__(self):
        return 'Person object (%s %s)' % (self.name, self.age)

quit()或exit()退出python shell,重复上面的操作,我们就可以看到:

In [1]: from people.models import Person

In [2]: Person.objects.get(name='liu')
Out[2]: <Person: Person object (liu 12)>

In [3]: Person.objects.get(age='12')
Out[3]: <Person: Person object (liu 12)>

In [4]: 

新建一个对象的方法有以下几种:

1. Person.object.create(name=name, age=age)
2. p = Person(name='liu', age=12)
   p.save()
3. p = Person(name='liu')
   p.age = 12
   p.save()
4. Person,object.get_or_create(name='liu', age=12)
# 这种方法式防止重复很好的方法,但是速度要相对慢一些,返回一个元组,第一个为Person对象,第二个为True或False,新建时返回的是True,已经存在时返回False。
In [11]: Person.objects.get_or_create(name='li', age=11)
Out[11]: (<Person: Person object (li 11)>, True)

In [12]: Person.objects.get_or_create(name='li', age=11)
Out[12]: (<Person: Person object (li 11)>, False)

获取对象有以下方法:

1. Person.objects.all()
2. Person.objects.all()[:10]切片擦操作,获取10个人,不支持副索引,切片可以节约内存。
3. Person.objects.get(name=name)
# get是用来获取一个对象的,如果需要满足条件的一些人,就要用到filter
4. Person.objects.filter(name='abc')  # 等于
   Person.objects.filter(name__exact="abc")  #名称严格等于“abc”得人
5. Person.objects.filter(name__iexact="abc")  # 名称为“abc”但是不区分大小写,可以找到ABC,Abc,aBC等等这些都符合条件
6. Person.objects.filter(name__icontains="abc")  # 名称中包含“abc”,且“abc”不区分大小写
7. Person.objects.filter(name__contains="abc")  # 名字中包含“abc”的人
8. Person.objects.filter(name__regex="^abc")  # 正则表达式查询
9. Person.objects.filter(name__iregex="^abc")  # 正则表达式不区分大小写
# filter是找出满足条件的,当然也有排除符合某条件的
10. Person.objects.exclude(name__contains="abc")  # 排除包含“abc”的Person对象
11. Person.objects.filter(name__contains="abc").exclude(age=12)  # 找出名称含有abc,但是排除年龄是12岁的
django ORM model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

1、多表链接查询:条件选取QuerySet的时候
filter表示=,exclude表示!=,querySet.distinct() 去重复

查询语句 语义
__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

例子:

In [2]: Person.objects.filter(age__gt=1)  # 年龄大于1岁的
Out[2]: <QuerySet [<Person: Person object (liu 12)>, <Person: Person object (liul 122)>, <Person: Person object (lius 11)>, <Person: Person object (li 11)>]>

q1.filter(pub_date__gte=datetime.date.today())表示为时间>=now,

补充:
“在django models中取得一个字段的distinct值”。就是select distinct xxx from table_name ...这样的功能。使用values会生成ValuesQuerySet(形如N个dict组成的list),猜测大数据无额外性能影响,毕竟queryset系列都是使用时才查询操作的。
xxxx.objects.values("field_name").distinct()
或者
xxxx.objects.distinct().values("field_name")

关于缓存:

# queryset是有缓存的
a = A.objects.all()
print [i for i in a]
#第一次执行打印会查询数据库,然后结果会被保存在queryset内置的cache中,再执行print的时候就会取自缓存。

# 很多时候会遇到仅需判断queryset是否为空的情况,可以:
if queryset:
  pass 
if queryset.count>0:
  pass 
if queryset.exists():
  pass. 
# 三种方式性能依次提升。

# 当queryset非常巨大时,cache会成为问题。此时可以:
queryset.iterator()
# 迭代器的用处就不多说了,根据具体需求情况使用。

相关文章

  • Django模型

    Django是怎么链接数据库的呢。 django模型映射关系:模型类 >>>>>>>>>>>>>>>数据库类属性>...

  • Python学习打call第五十七天:Django Model

    Django Model 模型 Django Model层是Django的数据模型层,每一个Model类就是数据库...

  • 数据模型操作(1)

    Django操作数据库 -----数据模型MVT:model数据模型部分 1. Django 连接数据库 修改项目...

  • 开发流程

    开发流程  创建 Django 项目 创建应用 模型 数据库配置 数据库表的定义 定义模型...

  • win10下解决django.core.exceptions.I

    问题 在做Django模型, 连接数据库时,报错:django.core.exceptions.Improperl...

  • 管理器 Manager

    管理器是 Django 的模型进行数据库的查询操作的接口 ,用于与数据库进行交互,Django 应用的每个模型都拥...

  • Django创建虚拟环境

    一 **** Django连接mysql数据库 1.Django模型配置数据库 2.在setting.py中进行...

  • Django模型定义

    Django 模型定义 Django 模型是使用 Python 代码对数据库中数据的描述,是数据的结构,包含数据的...

  • django框架-9模型(数据库)

    django模型里与数据库相关代码一般都写在models.py中 django模型支持sqlite3,Mysql,...

  • Django项目的开发二

    1、创建 Django 项目 2、创建应用 3、模型 1、数据库配置 2、数据库表的定义 3、定义模型...

网友评论

      本文标题:django模型(数据库)

      本文链接:https://www.haomeiwen.com/subject/mgpluxtx.html