博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django数据库主表从表
阅读量:7235 次
发布时间:2019-06-29

本文共 6921 字,大约阅读时间需要 23 分钟。

一对多

models.py

from django.db import models# Create your models here.# 数据库:一对多。它指的是两个表之间的关系,一指的是主表中的一条数据,多指的是从表中的多条数据。# 两个表:# 班级表(1班,2班,3班)# 学生表(张三-1班, 李四-1班, 王五-1班,赵六-2班,麻子-3班,小明-2班)# 这两个表:班级表就是主表,因为班级表的一条数据(比如1班)对应了学生表的多条数据(张三-1班, 李四-1班, 王五-1班),所以学生表是从表。class Classes(models.Model):    """    这是班级表,是主表;    """    c_name = models.CharField(max_length=20)    class Meta:        db_table = 'classes'class Student(models.Model):    """    这是从表,学生表;    主表中的一条数据可以对应从表中的多条数据;    从表中的一条数据只能对应主表中的一条数据;    """    s_name = models.CharField(max_length=20)    # 如何在从表中关联主表的ID?    # ForeignKey()外键,在Student表中,关联外部表Classes的主键,所以称为外键。    # on_delete:必须设置。表示从表数据所关联的主表数据被删除以后,从表应该怎么办。    # 1. CASCADE:如果主表数据删除,从表对应的数据也全部删除;    # 比如:张三、李四、王五关联的都是1班,如果1班这条数据被删除了,那么,对应的张三、李四、王五也全部删除;    # 2. SET_NULL:如果主表数据删除,从表数据保留,但是这种外键的关联关系classes_id设置为NULL。    # 从表关联两个主表的外键。    # related_name指定外键的关联名称,这个名称是用于将来查询数据使用的。只在主表查从表时会用到。    classes_one = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name='cls_one')    classes_two = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name='cls_two')    class Meta:        db_table = 'student'

 

views.py

from django.shortcuts import renderfrom django.views.generic import Viewfrom .models import Classes, Student# 通用视图类的用法:# 1. 主要作用还是用于配置url路由,只不过形式和视图函数的写法不一样,但是功能是一样的;视图函数区分GET和POST主要是通过request.method,而通用视图将GET和POST请求封装成了类中的两个方法;class Home(View):    def get(self, request, id):        print('------', id)        """        self和request是固定的两个参数,这两个参数后面如果还有参数,那就是url传递的参数;        :param request:        :return:        """        return render(request, 'index.html')    def post(self, request, id):        print('=======', id)        a = request.POST.get('a')        b = request.POST.get('b')        return render(request, 'index.html', {
'result': int(a)+int(b)})class DataHandler(View): def get(self, request): # 数据库中要先存在主表的数据,然后才能创建从表的数据。 # c1 = Classes(c_name='1班') # c1.save() # c2 = Classes(c_name='2班') # c2.save() # c3 = Classes(c_name='3班') # c3.save() # 关联主表id:通过classes(表面)或者classes_id(核心)都可以进行绑定; # s1 = Student(s_name="张三", classes_one=c1, classes_two=c1) # s1.save() # s2 = Student(s_name="李四", classes_id=c1.id) # s2.save() # s3 = Student(s_name="王五", classes=c2) # s3.save() # s4 = Student(s_name="赵六", classes_id=c3.id) # s4.save() # return render(request, 'index.html') # 如何根据主表的一条数据查询所有从表的数据? c1 = Classes.objects.get(id=1) # 语法:主表数据.从表名称_set # student_set就是一个查询结果集,所有的学生数据都在里面。 # stus = c1.student_set.all() # 如果从表出现,多个关联同一个主表的外键,就不能再使用student_set了,无法区分是classes_one还是classes_two。 stus = c1.cls_two.all() # 如何根据从表的一条数据查询对应的一条主表的数据? s1 = Student.objects.get(id=1) # classes就是s1对象的属性,是在Student类中声明的一个属性。 classes_name = s1.classes_two.c_name return render(request, 'index.html', {
'stus': stus})

 

一对一

models.py

from django.db import models# Create your models here.# ORM数据库的一对一关系:一个表中的一条数据对应着另外一个表中的一条数据。# 例如: 一个账户只对应着一个联系人,一个联系人只能有一个账户。身份证。class Account(models.Model):    """    一个账户类    """    # 账户名称    a_name = models.CharField(max_length=20)    # 账户密码    a_pwd = models.CharField(max_length=100)    # 账户激活的时间    # DateField()参数为空,这个字段的值需要自己添加。    # auto_now=True: 当这个Account这个对象的属性被修改了,在保存的时候,这个a_register_date这个时间会自动更新为保存时间;(强调更新时间)    # auto_now_add=True: 含义就是这个时间字段,不会随着对象的修改而更新这个时间,只在这个对象被第一次创建的时候自动填充创建的时间。以后也不会再变动了。(强调创建时间)    # auto_created=True: 表示使用当前时间作为值,自动创建这个字段的值。默认是False。当创建对象的时候就不需要给这个字段赋值了,会自动创建。    a_register_date = models.DateTimeField(auto_now_add=True, auto_created=True)    a_update_date = models.DateTimeField(auto_now=True)    class Meta:        db_table = 'account'class Contact(models.Model):    """    一个账户的拥有人。    """    # 所有人的姓名    c_name = models.CharField(max_length=20)    # 所有人的住址    c_address = models.TextField()    # 所有人的联系方式    c_phone = models.CharField(max_length=20)    # 添加账户和所有人的一对一关系。    # models.CASCADE:当account表中的一条数据删除时,对应的contact表中的数据也要删除。    account = models.OneToOneField(Account, on_delete=models.CASCADE)    class Meta:        db_table = 'contact'# 将models.OneToOneField写在哪一个表中,哪一个表就是从表;OneToOneField()的第一个参数就是主表;# OneToOneField不强调位置关系,两个表中任选一个作为主表,另一个作为从表;# 一对多:一必须是主表,多是从表,强调位置关系。

views.py

from django.shortcuts import renderfrom .models import Account, Contactfrom datetime import datetimedef add(request):    # 添加主表数据    a1 = Account(a_name='1@qq.com', a_pwd='123', a_register_date=datetime.now(), a_update_date=datetime.now())    a1.save()    a2 = Account(a_name='2@qq.com', a_pwd='456', a_register_date=datetime.now(), a_update_date=datetime.now())    a2.save()    # 添加从表数据    c1 = Contact(c_name='张三', c_address='北京', c_phone='111', account=a1)    c1.save()    c2 = Contact(c_name='李四', c_address='郑州', c_phone='222', account_id=a2.id)    c2.save()    return render(request, 'index.html', {
'result': '数据添加成功'})def select(request): # 根据主表的一条数据,查询从表的一条数据。也就是查询该账户的拥有人。 account = Account.objects.get(id=2) contact = account.contact.c_name # 根据从表的一条数据,查询主表的一条数据。也就是查询这个人的账户。 contact = Contact.objects.get(id=2) account = contact.account.a_name return render(request, 'index.html', {
'data': account})def update(request): account = Account.objects.get(id=1) account.a_pwd = '111' account.save() return render(request, 'index.html', {
'result': '数据修改成功'})def delete(request): Account.objects.get(id=1).delete() return render(request, 'index.html', {
'result': '数据删除成功'})

 

多对多

models.py

from django.db import models# Create your models here.# 多对多:一个表中的一条数据对应另外一个表中的多条数据;另外一个表中的一条数据对应着前一个表中的多条数据;class Publication(models.Model):    """    出版社(主表)    """    p_name = models.CharField(max_length=50)class Article(models.Model):    """    文章(从表)    """    a_name = models.CharField(max_length=50)    pub = models.ManyToManyField(Publication)# 一对多:ForginKey一定要设置在从表。# 一对一和多对多:关系可以设置在任意一个表中。

views.py

from django.shortcuts import renderfrom .models import *from django.http import HttpResponse# Create your views here.def index(request):    # 添加    # 一对一和一对多:先添加主表的数据,再添加从表的数据;    # 多对多:先分别添加两个表的数据,然后再进行关联;    # p1 = Publication(p_name='新华出版社')    # p1.save()    # p2 = Publication(p_name='东方出版社')    # p2.save()    #    # a1 = Article(a_name='个税改革')    # a1.save()    # a2 = Article(a_name='大桥通车')    # a2.save()    # 关联文章和出版社的关系    # a1这个文章关联的出版社是p1和p2,意思就是p1和p2两个出版社都出版了a1这个文章。    # a1.pub.add(p1, p2)    # a2.pub.add(p2)    # 查询:    # 1-根据主表数据查询从表数据;    # 查询 "东方出版社" 出版过的所有文章;    p1 = Publication.objects.get(id=2)    articles = p1.article_set.all()    for article in articles:        print(article.a_name)    # 2-根据从表数据查询主表数据;    # 查询 "个税改革" 这个文章,共有几个出版社出版;    a1 = Article.objects.get(id=1)    pubs = a1.pub.all()    for p in pubs:        print(p.p_name)    return HttpResponse('数据添加成功')

 

转载于:https://www.cnblogs.com/chensang/p/10002188.html

你可能感兴趣的文章
擦亮双眼,愚人节彩蛋回顾
查看>>
RDS全量物理备份谁才能读
查看>>
微软专家推荐11个Chrome 插件
查看>>
阿里数据库内核月报:2017年06月
查看>>
【案例】slave_net_timeout 问题一则
查看>>
根据搜索引擎网页去重原理来做seo
查看>>
Linux 系统挂载数据盘
查看>>
bootstrap 非原生checkbox 导致上级tr 点击两次的问题 真tm坑 研究了好久
查看>>
SQL SERVER 中is null 和 is not null 将会导致索引失效吗?
查看>>
CentOS 7.0安装配置LAMP服务器(Apache+PHP+MariaDB)
查看>>
HDOJ 2045 不容易系列之(3)—— LELE的RPG难题
查看>>
Mysql学习笔记(八)索引
查看>>
初探Java8中的HashMap(转)
查看>>
第一章(2)——预估和实际执行计划
查看>>
0324alter system checkpoing会写脏块吗
查看>>
使用GDB进行嵌入式远程调试
查看>>
文件剪切的sh脚本实现
查看>>
我的Android进阶之旅------>Android中Dialog系统样式讲解
查看>>
ffmpeg avpicture_fill的一些使用
查看>>
hisi出的H264码流结构
查看>>