一 . 一对多表ForeighKey(ORM)
1.创建ORM表
https://www.cnblogs.com/dangrui0725/p/9615641.html
一对多:子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择
共同点是在admin中添加数据的话,都会出现一个select选框,但只能单选,因为不论一对一还是一对多,自己都是“一”
class Colors(models.Model): colors=models.CharField(max_length=10) #蓝色 def __str__(self): return self.colors
class Clothes(models.Model): color=models.ForeignKey("Colors") #与颜色表为外键,颜色表为母表 description=models.CharField(max_length=10) #描述 def __str__(self): return self.description
增加数据
#增添子表数据,形式与一对一一致 #添加颜色为绿的服装:小帅哥 #方法1: models.Clothes.objects.create(color=models.Colors.objects.get(colors="绿"),description="小帅哥")
#方法1补充: models.Clothes.objects.create(color_id=models.Colors.objects.get(colors="绿").id,description="小帅哥")
#方法2: c_obj=models.Clothes(color=models.Colors.objects.get(colors="绿"),description="小帅哥") c_obj.save()
查询数据
#外键表联合查询: #外键子表查询母表,与一对一子表查询母表形式一致 #找到红裤衩所属的颜色表中的颜色--返回:红 #写法1: print(models.Clothes.objects.get(description="小虎哥").color.colors) #返回红,通过子表查询母表,写法:"子表对象.母表表名的小写.母表字段名" ;通过Clothes表查到description为"小虎哥",查找到对应colors
#写法2,反向从母表入手: print(models.Colors.objects.get(clothes__description="小虎哥").colors) #返回红,通过子表查询母表,但形式上是从母表对象自身直接获取字段,写法:"母表.objects.get(子表名小写__子表字段="xxx").母表字段名" ;效果和上边完全一致,另一种形式
#外键母表查询子表,与一对一形式不同,因为母表为"多",不能像一对一一样通过.get().子表.子表字段的方式获取,但与多对多母表查询子表一致 #找到颜色为红的所有服装--返回:[<Clothes: 大美女>, <Clothes: 小虎哥>] #写法1: color_obj=models.Colors.objects.get(colors="红") print(color_obj.clothes_set.all()) #注意:子表小写_set的写法,它实际上是一个QuerySet,可以用update,delete,all,filter等方法
#写法2: print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")))
#写法2简便写法(推荐): print(models.Clothes.objects.filter(color__colors="红")) #写法:filter(子表外键字段__母表字段='过滤条件')
#写法3: color_id=models.Colors.objects.get(colors="红").id #通过母表获取到颜色为红的id print(models.Clothes.objects.filter(color_id=color_id)) #filter得到QuerySet,写法:filter(子表外键字段_母表主键=母表主键对象)
备注:通过QuerySet的.values()方法,将QuerySet转化为ValuesQuerySet 双下方法
print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")).values('color__colors','description')) #获取子表的description字段,和母表的colors字段,获取母表字段写法: 子表外键字段名__母表字段名--适用于values()或filter() #简写形式补充:
print(models.Clothes.objects.filter(color__colors="红").values('color__colors','description')) #返回: [{'description': u'\u7ea2\u5185\u8863', 'color__colors': u'\u7ea2'}, {'description': u'\u7ea2\u5185\u88e4', 'color__colors': u'\u7ea2'}] #如果不加values(),返回的是[<Clothes: 大美女>, <Clothes: 小虎哥>]这样一个QuerySet集合,通过values可以形成一个列表,列表中的每一个元素是一个字典,可以通过list()将ValuesQeurySet转化为列表,之后返回给templates #另外可通过.values_list()将QuerySet转化为ValuesListQuerySet。返回:[(u'\u7ea2', u'\u7ea2\u889c\u5b50'), (u'\u7ea2', u'\u7ea2\u889c\u5b50')] #得到的是一个列表,列表中是多个元组,每个元组是ValuesQuerySet中字典的value,常用于从models里将数据取出后动态添加到前端模板中的select选项中。 #通过forms.py从models取值传给前端select选项,需重启django后,select选项才能更新,可在定义form时,添加如下关键字保障动态更新select选项 #forms.py from django import forms from test1 import models class ClothesForm(forms.Form): color=forms.IntegerField(required=True,widget=forms.Select(),) def __init__(self,*args,**kwargs): #定义这个关键字段,当使用form时,colors表新增了颜色,前端ClothesForm的color字段的选项会自动更新 super(ClothesForm, self).__init__(*args,**kwargs) self.fields['color'].wi
修改数据
#颜色为红的服装,description都更新为大美女 #写法1: models.Clothes.objects.filter(color__colors="红").update(description="大美女")
#写法2: models.Clothes.objects.filter(color_id=models.Colors.objects.get(colors="红").id).update(description="大美女")
#写法3: colors_obj=models.Colors.objects.get(colors="红") colors_obj.clothes_set.filter(id__gte=1).update(description="大美女") #其他写法参照一对一的修改和外键的查询
删除数据
models.Clothes.objects.get(description="灰裙子").delete() #对象和QuerySet都有方法delete()
models.Colors.objects.filter(colors="灰").delete()