• Django学习5


    多表相关操作

    三种关系 : 一对一 , 一对多 , 多对多

    创建表

    一对一:
    	xx = models.OneToOneField(to='表名',to_field='字段名',on_delete=models.CASCADE)	# 级联删除,# to_field可以不写,默认是关联到另一张表的主键
    一对多:
        xx = models.ForeignKey(to='表名',to_field='字段名',on_delete=models.CASCADE)
    多对多:
        xx = models.ManyToManyField(to='表名',)	# 自动创建第三张表
    
    示例:
    # 作者 <-一对一-> 作者信息
    # 出版社 <-一对多-> 书籍  (外键加在多的表里面)
    # 书籍 <-多对多-> 作者
    
    # 作者表
    class Author(models.Model): #比较常用的信息放到这个表里面
        # nid = models.AutoField(primary_key=True)		# id可以不写,默认会加上并设为主键
        name=models.CharField( max_length=32)
        age=models.IntegerField()
        authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)   # 一对一 
        def __str__(self):
            return self.name
    
    # 作者详细信息表(不常用的信息分到另一张表)
    class AuthorDetail(models.Model):#不常用的放到这个表里面
        # nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        # telephone = models.BigIntegerField()
        telephone=models.CharField(max_length=32)   # 方便后面模糊查询
        addr=models.CharField( max_length=64)
        def __str__(self):
            return self.addr
    
    # 出版社表
    class Publish(models.Model):
        # nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        city=models.CharField( max_length=32)
        email=models.EmailField()   # 实际上是CharField -- 数据字段验证,可以帮我们校验保存进来的数据是否为email格式的
        def __str__(self):
            return self.name
    
    # 书籍表
    class Book(models.Model):
        # nid = models.AutoField(primary_key=True)
        title = models.CharField( max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)
    
        publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE)
        authors=models.ManyToManyField(to='Author',)    # authors这个属性自动创建第三张表,建立多对多关系 不会生成字段
        def __str__(self):
            return self.title
    
    # 手动创建第三张表,连接书籍和作者多对多的关系(在orm中不方便使用,除非第三张表有自己独立的字段)
    # class BookToAuthor(models.Model):
    #     book_id = models.ForeignKey(to='Book')
    #     author_id = models.ForeignKey(to='Author')
    
    

    增删改查

    # 1.增
    # 1.1 一对一添加(作者表和作者信息表)
    new_author_detail = models.AuthorDetail.objects.create(
        birthday='1979-08-08',
        telephone='13838383838',
        addr='黑龙江哈尔滨'
    )
    obj = models.AuthorDetail.objects.filter(addr='山西临汾').first()
    # 方式一
    models.Author.objects.create(
        name='王涛',
        age=40,
        authorDetail=new_author_detail    # 放model对象 obj
    )
    # 方式二(常用)
    models.Author.objects.create(
        name='文洋',
        age=41,
        authorDetail_id=obj.id     # 放 mysql字段名称
    )
    
    # 1.2 一对多添加(书籍表和出版社表)
    # 方式一
    obj = models.Publish.objects.get(id=2)
    models.Book.objects.create(
        title='小李的床头故事',
        publishDate='2019-07-22',
        price=3,
        # publishs=models.Publish.objects.get(id=1),  # model对象
        publishs=obj,    # model对象
    )
    # 方式二(常用)
    models.Book.objects.create(
        title='小李的床头故事2',
        publishDate='2019-07-21',
        price=3.5,
        publishs_id=obj.id,  # mysql字段
    )
    
    # 1.3 多对多添加(作者表和书籍表)
    # 方式一(常用)
    book_obj = models.Book.objects.get(id=1)  # 找到书籍
    book_obj.authors.add(*[1,2])    # 找到第三张表并直接添加作者id,多个值用*[,]
    # 方式二
    author1 = models.Author.objects.get(id=1)  # 先找到2个作者
    author2 = models.Author.objects.get(id=3)
    book_obj = models.Book.objects.get(id=5)  # 找到书籍
    
    book_obj.authors.add(*[author1,author2])
    
    

    一对一和一对多的删除和单表删除操作一样
    # 一对一
        models.AuthorDetail.objects.get(addr='山西运城').delete()
        # 作者信息表删除信息,对应的作者也被级联删除了...
        models.Author.objects.get(id=3).delete()
        # 作者表删除信息,对应的作者信息不受影响!
        # 通俗点就是: 我和你关联,你不能随便删,会影响我.但我可以随便删,我不影响你(追星??)
    
    # 一对多(书籍表和出版社表)
        models.Publish.objects.get(id=1).delete()
        # 出版社表删除信息,对应出版的书也会一同删除
        models.Book.objects.get(id=1).delete()
        # 书籍表删除信息,对应的出版社不受影响
        
    # 多对多(书籍表和作者表)
        book_obj = models.Book.objects.get(id=6)
        # book_obj.authors.remove(*[4,])
        book_obj.authors.remove(*[4,6])
        
        book_obj.authors.clear()	# clear清空,全删的时候用
        book_obj.authors.set('1')   # 清空原来的记录,并重新添加(字符串)
        book_obj.authors.set(['4','6'])
    
    

    # 更新
    # 一对一
        models.Author.objects.filter(id=6).update(
        name='崔老师',
        age=16,
        # authorDetail=models.AuthorDetail.objects.get(id=6)
        authorDetail_id=4
        )
    # 一对多
        models.Book.objects.filter(id=4).update(
            # publishs=models.Publish.objects.get(id=3)
            publishs_id=2
        )
    # 多对多
    	上面删除的set方法
    
    # orm似乎没有级联更新的方法...
    models.Publish.objects.filter(id=2).update( 
            id=4		# 报错!
        )
    
    

    零碎知识点

    外部文件操作django的models:
        # 外部文件使用django的models,需要配置django环境
        import os
        if __name__ == '__main__':
            os.environ.setdefault("DJANGO_SETTINGS_MODULE", "singletablehw.settings")
            import django
            django.setup()
    
            from app01 import models
            .......
    
    
    时区问题:
        settings.py
        USE_TZ = False
    
    
    form表单中:
        novalidate   去除浏览器帮忙做的事
    
    
    python后端的url别名反向解析:
        urls.py:
            url(r'^lib/', views.lib, name='lib'), 
            url(r'^add_book/', views.add_book, name='add_book'),
        views.py:
            from django.urls import reverse     # 做urls别名反向解析的
            def add_book(request):
                ......
                # return redirect(reverse('lib'))
                return redirect('lib')	# redirect里用别名解析不用写reverse,直接写别名	不带参数的
            	
                print(reverse('delete_book',arg=(71,)))  # /delete_book/71/  带参数的
    
    前端html模板语法中的url别名反向解析:
    	<a href="{% url 'add_book' %}" class="btn btn-primary">添加书籍</a>		# 无参数的
        <a href="{% url 'edit_book' obj.id %}" class="btn btn-warning btn-sm">编辑</a>	# 有参数的
    
    
    查看mysql当前会话是否为严格模式
          select @@sql_mode;
    查看全局
          select @@global.sql_mode;
    
    
    使用django提供的admin:
        1.执行manage.py createsuperuser指令,创建超级管理员
        2.admin.py文件中注册要管理的表
            from app01 import models
            admin.site.register(models.Author)
            admin.site.register(models.AuthorDetail)
            admin.site.register(models.Publish)
            admin.site.register(models.Book)
        3.执行django项目,访问/admin/
          
    
    主键简写 --- pk
    (假设id为主键)  id=4 --- pk=4
        
    
  • 相关阅读:
    find the safest road HDU
    分页存储过程
    .NET Core与.NET Framework、Mono之间的关系
    winForm开发
    面试题目总结
    sqlserver锁表、解锁、查看锁表
    架构漫谈(四):如何做好架构之架构切分
    多线程讲解
    递归菜单简单应用
    杂记
  • 原文地址:https://www.cnblogs.com/straightup/p/13437069.html
Copyright © 2020-2023  润新知