Django ORM基本配置

到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:

  • 创建数据库,设计表结构和字段
  • 使用 MySQLdb 来连接数据库,并编写数据访问层代码
  • 业务逻辑层去调用数据访问层执行数据库操作

django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM),django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表;

1、修改project数据库配置(程序主目录下的settings.py文件)

默认连接数据库为本地文件sqlite3:

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.sqlite3',
  4. 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
  5. }
  6. }

更换为指定的mysql数据库:

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.mysql',
  4. 'NAME': 'mysite', #一定要存在的数据库名
  5. 'USER': 'xxxx',
  6. 'PASSWORD': 'xxx',
  7. 'HOST': '192.168.xx.xx',
  8. 'PORT': ''
  9. }
  10. }

2、创建定义数据库表结构文件(对应app目录下的models.py文件)

生成一个简单的数据库表:

  1. from django.db import models
  2.  
  3. # Create your models here.
  4.  
  5. class UserInfo(models.Model):
  6.  
  7. username = models.CharField(max_length=32)
  8. passwd = models.CharField(max_length=64)

把对应的app名称加入到settings.py文件配置里:

  1. INSTALLED_APPS = [
  2. 'django.contrib.admin',
  3. 'django.contrib.auth',
  4. 'django.contrib.contenttypes',
  5. 'django.contrib.sessions',
  6. 'django.contrib.messages',
  7. 'django.contrib.staticfiles',
  8. 'cmdb02',
  9. ]

3、生成数据库表

执行下面命令:

  1. python manage.py makemigrations
  2. python manage.py migrate # 生成数据表

注意:Django默认用的MysqlDB模块连接数据库,但在python3.x里面还没有这个模块,所有需要把连接数据库的模块改成pymsyql,修改project目录下的init.py文件

  1. import pymysql
  2. pymysql.install_as_MySQLdb()

执行生成数据库表命令,遇到的问题:

a.  django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.

解决: 找到 python_path\Lib\site-packages\django\db\backends\mysql路径下的base.py, 注释以下代码:

b.  AttributeError: 'str' object has no attribute 'decode'

解决:  找到 python_path\Lib\site-packages\django\db\backends\mysql路径下的operations.py, 修改以下代码:

query = query.encode(errors='replace')  将decode修改为encode

c. pymysql.err.InternalError: (1049, "Unknown database 'mysite'")

解决: 数据库创建数据库 mysite

django数据库增删改查,可以直接运行python文件,具体配置如下: 

新建python文件,设置django的配置:

  1. import django, os
  2. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj_test.settings') #设置django的配置文件
  3. django.setup()
  4. from user import models
  5. from django.db.models import Q
  6.  
  7. #新增
  8. # models.Nav.objects.create(name='哈哈哈')
  9.  
  10. # 对象实例化
  11. # nav = models.Nav(name='我的心情')
  12. # nav.save()

4. Django数据库单表操作

1. 增加:

    第一种写法:

  1. def ormadd(request):
  2. UserInfo.objects.create(username='root',passwd='')
  3. return HttpResponse('orm add')

 第二种写法:

  1. def ormadd(request):
  2. dicts = {'username': "xiaoxiao", 'passwd': ''}
  3. UserInfo.objects.create(**dicts)
  4. return HttpResponse('orm add')

  第三种写法:

  1. def ormadd(request):
  2. userinfo = UserInfo(username='sb2',passwd='')
  3. userinfo.save()
  4. return HttpResponse('orm add')

2.删除数据

  1. def ormdel(request):
  2. UserInfo.objects.filter(id=19).delete()
  3. return HttpResponse('orm dele')

3.更新数据

  第一种写法:

  1. def ormadd(request):
  2. UserInfo.objects.filter(id__gt=10).update(username='white')
  3. #id大于10的数据,更新name为101
  4. return HttpResponse('orm update')

第二种写法:

  1. def ormadd(request):
  2. dicts ={'username': 'black'}
  3. UserInfo.objects.filter(id__gt=10).update(**dicts)
  4. return HttpResponse('orm update')

4.查询数据

  1.  查询所有的数据
    1. def ormadd(request):
    2. res = UserInfo.objects.all() #QuerySet类型,列表里每个元素都是obj对象
    3. print(res) # <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
    4. for row in res:
    5. # 1 root 123456
    6. # 2 admin 123123
    7. print(row.id, row.username, row.passwd)
    8. return HttpResponse('orm select')

  2.查询指定字段

    1. def ormadd(request):
    2. res = UserInfo.objects.filter(username='root') #过滤后,结果为list
    3. #res = UserInfo.objects.filter(id=3) #根据id查询
    4. new_res = {}
    5. if res:
    6. for row in res:
    7. new_res['id'] = row.id
    8. new_res['username'] = row.username
    9. new_res['passwd'] = row.passwd
    10. return render(request, 'login.html', {'new_res':new_res})

    tmplate页面数据显示:

  3. 获取查询第一条数据 和 统计匹配个数

    1. def ormadd(request):
    2. #获取匹配的第一条数据
    3. obj = UserInfo.objects.filter(username='root').first()
    4. #获取匹配的字段个数
    5. c = UserInfo.objects.filter(username='root').count()
    6. return render(request, 'login.html', {'obj': obj, 'c': c})

    template页面数据显示:

 4. 比较值查询及多条件查询

  1. def ormadd(request):
  2. UserInfo.objects.filter(id=3, username='root') #id=1 且 name=root
  3. UserInfo.objects.filter(id__gt=1, username='root') #id>1 且 name=root
  4. UserInfo.objects.filter(id__lt=1) #id<1
  5. UserInfo.objects.filter(id__gte=1) #id>=1
  6. UserInfo.objects.filter(id__lte=1) #id<=1
    UserInfo.objects.filter(username__contains='root') #模糊查询
    UserInfo.objects.filter(id__range=(1,3)) #在什么范围
    UserInfo.objects.filter(id__in=[1,2,3,4,5,6]) #在什么范围
    UserInfo.objects.exclude(id=1) #排除id=1的数据
    from django.db.models import Q
    UserInfo.objects.filter(Q(username__contains='root')|Q(id__gte=1)) #username包含root 或者 id>=1的数据 或者关系

    5.外键反向查询

  1. #导航表结构
  2. class Nav(models.Model):
  3. name = models.CharField(max_length=64, unique=True, verbose_name='导航名称')
  4. is_delete = models.SmallIntegerField(default=1,verbose_name='是否被删除') #0已删
  5. create_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True) #插入数据自动转换为当前时间
  6. update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True) #修改时间自动转换为当前时间
  7.  
  8. def __str__(self):
  9. return self.name
  10.  
  11. class Meta:
  12. verbose_name = '导航表'
  13. verbose_name_plural = verbose_name
  14. db_table = 'nav' #指定表名
  15. # ordering=['create_time'] #查询数据时,默认按照 某个字段排序
  16.  
  17. #文章表结构
  18. class Article(models.Model):
  19. title = models.CharField(max_length=20, verbose_name='文章名称')
  20. content = models.TextField(verbose_name='文章内容',null=True)
  21. img = models.ImageField(upload_to='article_img',verbose_name='文章图片',null=True) #指定上传到哪个目录下
  22. nav = models.ForeignKey(Nav,verbose_name='导航表',on_delete=models.DO_NOTHING,db_constraint=False) #外键,对应导航表的数据删除后,该表不需要删除; db_contraint不建立真正的外键关系
  23. is_delete = models.SmallIntegerField(default=1, verbose_name='是否被删除')
  24. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) # 插入数据自动转换为当前时间
  25. update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True) # 修改时间自动转换为当前时间
  26.  
  27. def __str__(self):
  28. return self.title
  29.  
  30. class Meta:
  31. db_table='article'
  32.  
  33. #外键反向查询
  34. nav = models.Nav.objects.get(name='python')
  35. res_a = nav.article_set.all() #查导航下所有的文章
  36. print(res_a)

6. 多对多关联 表结构

表设计:

  1. from django.db import models
  2. from utils import tools
  3. from earth import settings
  4.  
  5. class BaseModel(models.Model):
  6. '''公共字段'''
  7. is_delete_choice = (
  8. (0, '删除'),
  9. (1, '正常')
  10. )
  11. is_delete = models.SmallIntegerField(choices=is_delete_choice, default=1, verbose_name='是否被删除')
  12. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) # auto_now_add的意思,插入数据的时候,自动取当前时间
  13. update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True) # 修改数据的时候,时间会自动变
  14.  
  15. class Meta:
  16. abstract = True # 只是用来继承的,不会创建这个表
  17.  
  18. class Author(BaseModel):
  19. name = models.CharField(verbose_name='名称', max_length=20)
  20.  
  21. def __str__(self):
  22. return self.name
  23.  
  24. class Meta:
  25. verbose_name = '作家'
  26. verbose_name_plural = verbose_name
  27. ordering = ['id']
  28. db_table = 'eg_author'
  29.  
  30. class Book(BaseModel):
  31. name = models.CharField(verbose_name='书名', max_length=20)
  32. price = models.FloatField(verbose_name='价格')
  33. count = models.IntegerField(verbose_name='数量')
  34. # author = models.ForeignKey(Author, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name='作者')
  35. author = models.ManyToManyField(Author, verbose_name='作者') #多对多关联, 1个作者可以有多本书; 1本书可以有多个作者翻译
  36.  
  37. def __str__(self):
  38. return self.name
  39.  
  40. class Meta:
  41. verbose_name = '书籍'
  42. verbose_name_plural = verbose_name
  43. ordering = ['id']
  44. db_table = 'eg_book'

model_test.py, 多对多关联查询(正向、反向)

  1. import django,os
  2. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'earth.settings') #设置django的配置文件
  3. django.setup()
  4.  
  5. from example import models
  6.  
  7. #新增作者
  8. models.Author.objects.create(name='dsx')
  9. models.Author.objects.create(name='niuniu')
  10.  
  11. #新增书
  12. models.Book.objects.create(name='自动化1',price=18,count=2)
  13. models.Book.objects.create(name='自动化2',price=18,count=3)
  14. models.Book.objects.create(name='自动化3',price=18,count=4)
  15.  
  16. #获取2张表的数据
  17. a1 = models.Author.objects.filter(id=4).first()
  18. a2 = models.Author.objects.filter(id=5).first()
  19. b1 = models.Book.objects.filter(id=9).first()
  20. b2 = models.Book.objects.filter(id=10).first()
  21.  
  22. #创建多对多关系,以Book表为基础
  23. b1.author.add(a1)
  24. b1.author.add(a2)
  25. b2.author.add(a1)
  26. b2.author.add(a2)
  27.  
  28. #多对多关系查询,正向查询
  29. a = b1.author.all() #b1这本书对应的作者,正向查询
  30. print(a)
  31.  
  32. #反向查询
  33. b = a1.book_set.all() # 根据a1作者查询有几本书,反向查询
  34. print(b)
  35.  
  36. #解除多对多关系
  37. b1.author.remove(a1) #解除书1与作者1的关系
  38.  
  39. #清除关系
  40. b2.author.clear() #清除b2这本书对应的所有作者

django 分页:

  1. from django.core.paginator import Paginator
  2. #整体分页功能
  3. m = list(range(100))
  4. page_obj = Paginator(m,20)
  5. print(page_obj.count) #总共多少数据
  6. print(list(page_obj.get_page(1))) #获取第几页数据
  7. print(page_obj.num_pages) #总共分几页 ,100/20 = 5页
  8. print(page_obj.page_range) #分页范围,默认分页范围
  9.  
  10. #某页的功能
  11. page1 = page_obj.get_page(1)
  12. page1.has_next() #判断是否有下一页
  13. page1.has_other_pages() #是否有其他页
  14. page1.has_previous() #是否有上一页
  15. page1.next_page_number() #下一页的页数
  16. page1.previous_page_number() #上一页页码
  17. page1.end_index() #末尾页
  18. page1.start_index() #首页
  1. page1.number #当前页码
  1. page1.paginator #获取分页对象

django查询count、group_by功能

  1. SQLselect department,count(*) from EmployeeInfo group by department;
  2.  
  3. from django.db.models import Count
  4.  
  5. result = EmployeeInfo.objects.values('department').annotate(Count=Count('department')).order_by()

#例子:

html:

  1. {% block pagination %}
  2. {# 判断是否有其他分页#}
  3. {% if artciles.has_other_pages %}
  4. <div>
  5. <ul class="pagination">
  6. {# 判断是否有上一页#}
  7. {% if artciles.has_previous %}
  8. <li><a href="/index/?limit={{ page_limit }}&page={{ artciles.previous_page_number }}">«</a></li>
  9. {% endif %}
  10.  
  11. {# 分页范围#}
  12. {% for num in artciles.paginator.page_range %}
  13. {% if num == artciles.number %}
  14. <li><a class="active" href="/index/?limit={{ page_limit }}&page={{ num }}">{{ num }}</a></li>
  15. {% else %}
  16. <li><a href="/index/?limit={{ page_limit }}&page={{ num }}">{{ num }}</a></li>
  17. {% endif %}
  18. {% endfor %}
  19.  
  20. {# 判断是否有下一页#}
  21. {% if artciles.has_next %}
  22. <li><a href="/index/?limit={{ page_limit }}&page={{ artciles.next_page_number }}">»</a></li>
  23. {% endif %}
  24. </ul>
  25. </div>
  26. {% endif %}
  27. {% endblock %}

view 代码:

  1. def index(request):
  2. limit = request.GET.get('limit', page_limit)
  3. page = request.GET.get('page', 1)
  4.  
  5. artciles = models.Article.objects.all().order_by('id') #查mysql
  6. page_obj = Paginator(artciles, limit) #对文章进行分页, (7,2)
  7. page_data = page_obj.get_page(page) #获取某页数据
  8. return render(request, 'index.html', {'artciles':page_data})

Django之数据库对象关系映射的更多相关文章

  1. 优酷项目之 ORM(数据库对象关系映射)代码重写

    前言: 我们在操作数据库时候一般都是通过sql代码来操作mysql数据库中相关数据,这就需要懂得sql语句,那么怎么样才能在不懂sql语句的情况下通过我们所学的python代码来实现对mysql数据库 ...

  2. Python Web框架篇:Django Model ORM(对象关系映射)

    一,基本操作 用于实现面向对象编程语言里不同类型系统的数据之间的转换,换言之,就是用面向对象的方式去操作数据库的创建表以及增删改查等操作. 1.增(create , save): from app01 ...

  3. web前端基础知识-(八)Django进阶之数据库对象关系映射

    Django ORM基本配置 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...

  4. Python之路【第十九章】:Django 数据库对象关系映射

    Django ORM基本配置 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...

  5. web框架-(四)Django进阶之数据库对象关系映射

    Django ORM基本配置 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去 ...

  6. Daject初探 - 一个开源关系型数据库对象关系映射(ORM)模型

    Daject简介 Daject是用php写的一个关系型数据库抽象模型,通过该模型,可以在不写任何SQL或写很少的SQL就能执行大多数数据库查询操作.Daject具有面向对象,跨数据库的优点,通过数据库 ...

  7. Django 源码小剖: Django 对象关系映射(ORM)

    引 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django O ...

  8. $Django setting.py配置 ,GET、POST深入理解,三件套,orm对象关系映射简介

    1 django中app的概念: 大学:----------------- 项目  信息学院 ----------app01  物理学院-----------app02 ****强调***:创建的每一 ...

  9. Python学习---django之ORM语法[对象关系映射]180124

    ORM语法[对象关系映射] ORM: 用面向对象的方式去操作数据库的创建表以及增删改查等操作. 优点:1 ORM使得我们的通用数据库交互变得简单易行,而且完全不用考虑该死的SQL语句.快速开发. 2 ...

随机推荐

  1. HTML中使用图像

    插入图像 在页面中插入图像的标记只有一个,就是img标记. 语法为:<img src="图片地址" alt="下载失败时的替换文本" title='提示文 ...

  2. Song Form

    First of all, song form is an indepentent concept from the boxes, boxes simply describe the way the ...

  3. GlusterFS分布式存储系统

    一,分布式文件系统理论基础 1.1 分布式文件系统出现 计算机通过文件系统管理,存储数据,而现在数据信息爆炸的时代中人们可以获取的数据成指数倍的增长,单纯通过增加硬盘个数来扩展计算机文件系统的存储容量 ...

  4. JDK环境变量配置linux

    安装前先查看是否安装过jdk如果安装过则 卸载 1. 确定JDK的版本: rpm -qa | grep jdk rpm -qa | grep gcj 可能的结果是: libgcj-4.1.2-42.e ...

  5. HMM 模型输入数据处理的优雅做法 来自实际项目

    实际项目我是这样做的: def mining_ue_procedures_behavior(seq, lengths, imsi_list): print("seq 3:", se ...

  6. pypython解构

    *******重点 解构:把线性结构的元素解开,并按顺序的赋给其他变量 左边接纳的要与右边解开的个数一致. lst = [3,5] first,second = lst print(first,sec ...

  7. TListView控件的ReadOnly属性的一个Bug

    不知道是不是ListView的 ReadOnly属性的一个bug 1.Form上一个ListView,如图设置 2.在FormCreate事件中写如下代码:     ListView1->Rea ...

  8. js获取此刻时间或者把日期格式时间转换成字符串格式的时间

    getTime(val){ if (val&val instanceof Date){ d = val; }else{ d = new Date(); }; var year = d.getF ...

  9. npm link的使用

    npm link的使用 https://www.jianshu.com/p/aaa7db89a5b2

  10. cvte2018春招前端开发实习面试分享

    编程题问题描述: 返回整数数组中出现次数第n多的数字(返回值可能有多个) 最近在找实习,面试二面最后出了一道这样的编程题,当时有思路但语法有错误,而且很紧张,最后没有运行出来,导致凉凉,回来重新思考了 ...