Django中的ORM进阶操作
Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互。但是仍然有几种操作是非常绕也特别容易混淆的。于是,针对这一块,来一个分类总结吧。
对于ORM对数据库的基本操作前面model里已经有了介绍,这里专门针对ORM的一对多、多对多、正向、反向等操作来讲解用法和注意事项。
铭记于心的两条:
- 在联表操作过滤查找数据时用双下划线 "__"
- 在取数据时用点 "."
一、一对多
首先来设计两张简单的表格,并在其中一张表中设置一个另外一张表的外键值
# --*-- coding:utf-8 -*- from django.db import models class UserType(models.Model): caption = models.CharField(max_length=32) class UserInfo(models.Model): user_type = models.ForeignKey(UserType) username = models.CharField(max_length=32) age = models.IntegerField()
1、添加数据:
传id的方式:(字典的形式传参)
user_dict = {"username": "chenchao", "age": "18", "user_type_id": 1} models.UserType.objects.create(**user_dict)
传对象的方式:
user_type_obj = models.UserType.objects.get(id=1) #先获取外键表中的数据对象 user_dict = {"username": "chenchao", "age": "18", "user_type": user_type_obj} #将对象传入字典 models.UserType.objects.create(**user_dict)
讲解:在我们写的models类时,外键的字段是”user_type",而django在数据库中保存字段时默认会在后面加“_id”,所以可以直接通过传id的方式。
而在表中的外键字段“user_type”又代表的是字典表中的一行数据对象。于是同样可以传对象的方式来传参。
2、删除数据
3、修改数据 (这两个操作与上面的添加用法基本一致)
4、查找数据
正向查找:(基于存在外键值表的查找为正向)
models.UserInfo.objects.filter(user_type__caption= "CEO") #查找用户类型为CEO的所有用户, 双下划线”__“
反向查找:(基于不存在外键值表的查找为反向查找,前提是两张表已经建立了关系)
- 我们创建的外键表有两个字段,id、caption。但Django默认在外键的表里还会埋藏一个字段为userinfo。可以get一个表中不存在的值,通过返回的报错黄页里面可以查看到。
- 通过models获取的值都是Qureyset。只要是这个类型就可以用.filter .all .count方法
- 我们知道user_type_obj获取的是外键表中的一行数据对象。
- user_type_obj.id 代表一个数据
- user_type_obj.caption 代表一个数据
- user_type_obj.userinfo_set 特殊,代表的是一种能力。这个能力就可以获取到这个用户类型下的所有用户或者某几个用户
- request.user 代指的是django自带的auth表里的一行数据,与userinfo做了一个OneToOne,与正向查询是一样的。所以也可以用request.user.userinfo.filter....
举例:获取某个人是什么用户类型?当前用户类型下有多少人?
user_type_obj = models.UserType.objects.get(userinfo__username= "chenchao") #通过外键表来找到隐藏的userinfo字段下的username user_type_obj.caption # 获取用户chenchao的用户类型 user_type_obj.userinfo_set.all().count() #获取此类型下的所以用户个数
点赞的例子:
首先设计一下数据库表结构,使点赞的一张表与用户和文章建立外键关系
class MyUser(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=64) def __unicode__(self): return self.username class News(models.Model): title = models.CharField(max_length=32) content = models.CharField(max_length=32) def __unicode__(self): return self.title class Favor(models.Model): user_obj = models.ForeignKey(MyUser) new_obj = models.ForeignKey(News) def __unicode__(self): return "%s -> %s" %(self.user_obj.username, self.new_obj.title)
时间: 2024-11-03 05:42:42