在Python中如何操作数据库中表与表之间的关系
===========================实例一(onetoone)=======================
1.models.py
from django.db import models
# 表之间数据的一对一关系:一个账户对应一个联系人,反过来一个联系对应一个账户
# 主表 从表
# 账户表
class Account(models.Model):
aname = models.CharField(max_length=20)
apwd = models.CharField(max_length=16)
adate = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'account'
def __str__(self):
return '{}'.format(self.aname)
class Concat(models.Model):
# 一个联系人要对应一个账户
# OneToOneField() 一对一
# 1.对应的数据模型类 on_delete 当主表中的数据被删除时,从表中的数据如何处理
# on_delete=models.CASCADE 当主表中的数据删除时,从表数据也一并删除
account = models.OneToOneField(Account, on_delete=models.CASCADE)
# 当前表中的字段
address = models.CharField(max_length=255)
phone = models.CharField(max_length=11)
class Meta:
db_table = 'concat'
def __str__(self):
# self.account.aname 就是Account模型类对象的aname属性值
return 'Concat:{}'.format(self.account.aname)
2.views.py
from django.shortcuts import render,HttpResponse
from .models import Account,Concat
# Create your views here.
def add(request):
# 先创建主表中的数据
account = Account(aname='王老师', apwd='5235323', adate='2018-4-5')
account.save()
# account = Account.objects.get(id=4)
# 将account和一个concat进行一对一的绑定
# account参数必须是Account中的一条数据
concat = Concat(account=account, address='zzz', phone='110')
concat.save()
return HttpResponse('成功')
def select(request):
# 1.通过从表查询主表中对应的数据
concat = Concat.objects.get(id=3)
# concat.account 这就是主表中的数据模型对象
print(concat.account.aname, concat.account.apwd, concat.account.adate)
# 2.通过主表中字段查询从表中的数据
# 从表中的一对一字段名__主表字段___条件
# account__aname__contains =
concat = Concat.objects.get(account__aname__contains='小明')
print(concat.address)
print(concat.phone)
print(concat.account.aname)
print(concat.account.adate)
return HttpResponse('成功......')
def delete(request):
# 1.删除从表数据,不会对主表造成影响
# Concat.objects.get(id=2).delete()
# 2.删除主表数据
Account.objects.get(id=3).delete()
========================实例二(onetomany)=====================
1.models.py
from django.db import models
# 数据库中数据一对多关系:例如 一个班级(主表)对应多个学生(从表)
# 班级表(主表)
class Classes(models.Model):
cname = models.CharField(max_length=50)
cnumber = models.IntegerField(null=False)
class Meta:
db_table = 'classes'
class Students(models.Model):
sname = models.CharField(max_length=20)
sage = models.IntegerField(null=True)
sex = models.BooleanField(choices=((True,'男'),(False,'女')),default=True)
# 建立和班级的一对多关系
# 通过设置外键建立一对多关系
classes = models.ForeignKey(Classes,on_delete=models.CASCADE)
class Meta:
db_table = 'students'
2.views.py
from django.shortcuts import render,HttpResponse
from .models import Classes,Students
def add(request):
# 先创建classes数据
c1 = Classes(cname='python7期',cnumber=22)
c1.save()
c2 = Classes(cname='python8期',cnumber=35)
c2.save()
c3 = Classes(cname='python9期',cnumber=30)
c3.save()
s1 = Students(classes=c1,sname='张三',sage=22,sex=1)
s1.save()
s1 = Students(classes=c1,sname='李四', sage=21, sex=0)
s1.save()
s1 = Students(classes=c1,sname='王五', sage=23, sex=1)
s1.save()
s1 = Students(classes=c2,sname='赵六', sage=24, sex=0)
s1.save()
s1 = Students(classes=c3,sname='赵四', sage=21, sex=1)
s1.save()
s1 = Students(classes=c3,sname='刘能', sage=23, sex=1)
s1.save()
s1 = Students(classes=c3,sname='谢大脚', sage=20, sex=0)
s1.save()
return HttpResponse('成功....')
def select(request):
#1.根据从表数据查询主表数据
s = Students.objects.get(id=8)
# 获取主表数据
print(s.classes.cname)
print(s.classes.cnumber)
# 2.查询赵四所在的班级及班级人数
s2 = Students.objects.get(sname='赵四')
print(s2.classes.cname)
print(s2.classes.cnumber)
# 3.查询赵四所在班级的所有学员
# res = Students.objects.filter(classes=s2.classes)
# 获取班级对应的所有学员集合
# classes.students_set 班级对应的学员集合
res = s2.classes.students_set.all()
for r in res:
print(r.sname)
# 根据班级名称查找所有的学员
# c2 = Classes.objects.get(id=4)
# Students.objects.filter(classes=c2)
# 等同于下面这种写法
c2 = Classes.objects.get(cname='python7期')
res = c2.students_set.all()
# c2.students_set.filter()
# c2.students_set.get()
for r in res:
print(r.sname)
return HttpResponse('///////')
def delete(request):
# 直接删除主表中的数据
# 从表中有数据的外键对应这个主表数据,会一并把从表中的数据进行删除(先删除从表数据,再删除主表数据)
# Classes.objects.get(id=4).delete()
# 删除从表中的数据,不会对主表数据造成影响
Students.objects.get(sname='赵四').delete()
return HttpResponse('//////')
=====================实例三(manytomany)=================
1.models.py
from django.db import models
# 数据库中数据的多对多关系:一个表中的一条数据,对应着另外一个表中多条数据,反过来也是一样
# 一篇文章可以在多个出版社出版,一个出版社可以出版多篇文章
class Publication(models.Model):
pname = models.CharField(max_length=50)
paddress = models.CharField(max_length=100)
class Meta:
db_table = 'publication'
class Article(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=20)
# 绑定多对多关系,ManyToManyField()
publication = models.ManyToManyField(Publication)
class Meta:
db_table = 'article'
# 用户评论表: 用户名/评论/时间/ 文章表:文章标题/文章内容/作者
2.views.py
from django.shortcuts import render,HttpResponsefrom .models import Publication,Article
def add(request):
p1 = Publication(pname='新华社',paddress='北京')
p1.save()
p2 = Publication(pname='人民出版社', paddress='北京')
p2.save()
p3 = Publication(pname='清华出版社', paddress='北京')
p3.save()
p4 = Publication(pname='蓝翔出版社', paddress='山东')
p4.save()
a1 = Article(title='python教程',author='张三')
a1.save()
a2 = Article(title='java教程',author='李四')
a2.save()
a3 = Article(title='php教程',author='王五')
a3.save()
a4 = Article(title='HTML教程',author='赵四')
a4.save()
a5 = Article(title='Javascript教程',author='刘能')
a5.save()
# 如果是多对多关系,一定要将两张表中的数据保存成功后,在关联中间表
# add使用add函数,中间表中添加记录
# 如果是多对多关系,一定要将两张表中的数据保存成功后,在关联中间表
# add使用add函数,中间表中添加记录
# 如果是多对多关系,一定要将两张表中的数据保存成功后,在关联中间表
# add使用add函数,中间表中添加记录
# add添加对应的出版社
a1.publication.add(p1,p2)
a1.publication.add(p3)
a2.publication.add(p2,p3,p4)
a3.publication.add(p3,p4)
a4.publication.add(p1,p4)
a5.publication.add(p1,p2,p3,p4)
return HttpResponse('成功........')
def select(request):
# 1.根据article对象,查询publication模型对象数据
a1 = Article.objects.get(id=3)
# 获取publication模型对象
# 获取这篇文章对应的所有出版社
res = a1.publication.all()
for r in res:
# r就是一个出版,获取出版社出版的所有文章
ares = r.article_set.all()
# 循环遍历该出版社出版的每一篇文章
for re in ares:
print(r.pname,re.title )
# 2.根据Pubilcation对象查询该出版社出版的article对象数据
p1 = Publication.objects.get(id=3)
res = p1.article_set.all()
for r in res:
# 每一个r就是一篇文章
print(r.title,r.author)
return HttpResponse('///////')
def delete(request):
a = Article.objects.get(id=4)
res = a.publication.all()
for r in res:
# 解除数据之间的关联
a.publication.remove(r)
# 删除对应的数据
a.delete()
return HttpResponse('////')