Django数据库关系
创建时间:
阅读:
Django数据库
区分一对一,多对多
一对一:子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表不可以再选择母表中已被选择的那条数据
一对多:子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择
共同点是在admin中添加数据的话,都会出现一个select选框,但只能单选,因为不论一对一还是一对多,自己都是“一”
多对多总结:
比如有多个孩子,和多种颜色、
每个孩子可以喜欢多种颜色,一种颜色可以被多个孩子喜欢,对于双向均是可以有多个选择
应用场景
一对一:一般用于某张表的补充,比如用户基本信息是一张表,但并非每一个用户都需要有登录的权限,不需要记录用户名和密码,此时,合理的做法就是新建一张记录登录信息的表,与用户信息进行一对一的关联,可以方便的从子表查询母表信息或反向查询
外键:有很多的应用场景,比如每个员工归属于一个部门,那么就可以让员工表的部门字段与部门表进行一对多关联,可以查询到一个员工归属于哪个部门,也可反向查出某一部门有哪些员工
多对多:如很多公司,一台服务器可能会有多种用途,归属于多个产品线当中,那么服务器与产品线之间就可以做成对多对,多对多在A表添加manytomany字段或者从B表添加,效果一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from django.db import models
class Colors(models.Model): colors=models.CharField(max_length=10) def __str__(self): return self.colors class Ball(models.Model): color=models.OneToOneField("Colors") description=models.CharField(max_length=10) def __str__(self): return self.description class Clothes(models.Model): color=models.ForeignKey("Colors") description=models.CharField(max_length=10) def __str__(self): return self.description class Child(models.Model): name=models.CharField(max_length=10) favor=models.ManyToManyField('Colors')
|
一对一
查:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
print(models.Ball.objects.get(description="红球").color.colors)
print(models.Colors.objects.get(ball__description="红球").colors)
print(models.Colors.objects.get(colors="红").ball.description)
print(models.Ball.objects.get(color__colors="红").description)
|
增:
1 2 3 4 5 6
| color_obj=models.Colors.objects.create(colors="黑")
models.Ball.objects.create(color=color_obj,description="黑球")
|
###备注:增添数据的三种常用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
color_obj=models.Colors.objects.create(colors="黑") models.Ball.objects.create(color=color_obj,description="黑球")
color_id=models.Colors.objects.create(colors="黑").id models.Ball.objects.create(color_id=color_id,description="黑球")
color_obj=models.Colors.objects.create(colors="黑") ball_obj=models.Ball(color=color_obj,description="黑球") ball_obj.save()
color_obj=models.Colors.objects.create(colors="黑") ball_dic={'description':"黑球"} models.Ball.objects.create(color=color_obj,**ball_dic)
|
###改:
1 2 3 4 5 6 7 8
| color_obj=models.Colors.objects.get(colors="黑")
color_obj.colors="灰" color_obj.save()
models.Ball.objects.filter(description="黑球").update(color=color_obj,description="灰球")
|
###备注:修改数据的常见方式
1 2 3 4 5 6 7 8 9 10 11 12
| color_obj=models.Colors.objects.get(colors="黑") color_obj.colors="灰" color_obj.save()
models.Ball.objects.filter(color__colors="红").update(description="灰球")
up_dic={"description":"灰球"} models.Ball.objects.filter(id__gt=0).update(**up_dic)
|
删:
1 2 3 4 5
| models.Ball.objects.get(description="灰球").delete()
models.Colors.objects.filter(colors="灰").delete()
models.Colors.objects.all().delete()
|
##一对多(外键)
查:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
print(models.Clothes.objects.get(description="小虎哥").color.colors)
print(models.Colors.objects.get(clothes__description="小虎哥").colors)
color_obj=models.Colors.objects.get(colors="红") print(color_obj.clothes_set.all())
print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")))
print(models.Clothes.objects.filter(color__colors="红"))
color_id=models.Colors.objects.get(colors="红").id
print(models.Clothes.objects.filter(color_id=color_id))
|
备注:
通过QuerySet的.values()方法,将QuerySet转化为ValuesQuerySet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")).values('color__colors','description'))
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'}]
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): super(ClothesForm, self).__init__(*args,**kwargs) self.fields['color'].widget.choices=models.Colors.objects.all().order_by('id').values_list('id','colors')
|
增:
1 2 3 4 5 6 7 8 9 10
|
models.Clothes.objects.create(color=models.Colors.objects.get(colors="绿"),description="小帅哥")
models.Clothes.objects.create(color_id=models.Colors.objects.get(colors="绿").id,description="小帅哥")
c_obj=models.Clothes(color=models.Colors.objects.get(colors="绿"),description="小帅哥") c_obj.save()
|
改:
1 2 3 4 5 6 7 8 9
|
models.Clothes.objects.filter(color__colors="红").update(description="大美女")
models.Clothes.objects.filter(color_id=models.Colors.objects.get(colors="红").id).update(description="大美女")
colors_obj=models.Colors.objects.get(colors="红") colors_obj.clothes_set.filter(id__gte=1).update(description="大美女")
|
删:
1 2 3 4
| models.Clothes.objects.get(description="灰裙子").delete()
models.Colors.objects.filter(colors="灰").delete()
|
多对多
###查:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
child_obj=models.Child.objects.get(name="小明")
print(child_obj.favor.all())
print(models.Colors.objects.filter(child__name="小明"))
color_obj=models.Colors.objects.get(colors="黄") print(color_obj.child_set.all())
print(models.Child.objects.filter(favor=models.Colors.objects.get(colors="黄")))
print(models.Child.objects.filter(favor__colors="黄"))
color_id=models.Colors.objects.get(colors="黄").id
print(models.Child.objects.filter(favor=color_id))
|
增与改
(增添子表或母表数据参照一对一的增,多对多重点在于关系表的对应关系变更):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
child_obj=models.Child.objects.create(name="小虎")
colors_obj=models.Colors.objects.all()
child_obj.favor.add(*colors_obj)
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.all() child_obj.favor=colors_obj child_obj.save()
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.filter(colors__in=["蓝","黄"])
child_obj.favor.clear()
child_obj.favor.add(*colors_obj)
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.get(colors="绿") child_obj.favor.clear() child_obj.favor.add(colors_obj)
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.get(colors="蓝") colors_obj.child_set.add(child_obj)
children_obj=models.Child.objects.all() colors_obj=models.Colors.objects.get(colors="蓝") colors_obj.child_set.add(*children_obj)
|
删:删除多对多关系:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.all() child_obj.favor='' child_obj.save()
child_obj=models.Child.objects.get(name="小虎") colors_obj=models.Colors.objects.all() child_obj.favor.remove(*colors_obj)
child_obj=models.Child.objects.get(name="小虎") child_obj.favor.clear()
children_obj=models.Child.objects.all() colors_obj=models.Colors.objects.get(colors="蓝") colors_obj.child_set.remove(*children_obj)
colors_obj=models.Colors.objects.get(colors="蓝") colors_obj.child_set.clear()
|
删多对多表数据:
1 2 3 4 5 6
|
colors_obj=models.Colors.objects.get(colors="蓝") colors_obj.child_set.all().delete()
models.Child.objects.all().delete()
|
删除母表数据:
默认情况下,比如列中,删除’红‘色,那么子表与颜色表是一对一或者外键关系的数据会自动删除,比如红球,小虎哥,
与颜色表是多对多关系的话,不会自动删除喜欢红色的人,热水去掉红色已选
如果想让与母表外键关联的子表在删除外键之后依旧可以保留子表的数据,需要子表建表时加入以下字段:
1 2 3 4 5
| class Clothes(models.Model): color=models.ForeignKey("Colors",null=True,on_delete=models.SET_NULL)) description=models.CharField(max_length=10)
|
choice
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
class Child(models.Model): sex_choice=((0,"男"),(1,"女")) name=models.CharField(max_length=10) favor=models.ManyToManyField('Colors') sex=models.IntegerField(choices=sex_choice,default=0) def __unicode__(self): return self.name
child_obj=models.Child.objects.get(name="小虎") print(child_obj.sex) print(child_obj.get_sex_display())
|
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com