zoukankan      html  css  js  c++  java
  • 图书多表操作相关笔记

    1. 创建数据库

    cmd终端 create database book01;

    ​ show tables;

    2. 创建django项目 book01

    settings配置

    数据库设置

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': "book01",    # cmd创建的数据库名称
            "USER": "root",      # 连接数据库的用户名
            "PASSWORD": "123",   # 连接数据库的密码
            "HOST": "127.0.0.1", # 连接主机,默认本级
            "PORT": 3306,        #  端口 默认3306
        }
    }
    

    静态文件配置

    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,"statics")
    

    settings同级init.py

    import pymysql
    pymysql.install_as_MySQLdb()
    

    models.py添加表关系

    from django.db import models
    
    # Create your models here.
    
    class Author(models.Model):
        # nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        au = models.OneToOneField(to="AuthorDetail",)
    
        def __str__(self):
            return self.name
    
    class AuthorDetail(models.Model):
    
        # nid = models.AutoField(primary_key=True)
        birthday = models.DateField()
        telephone = models.BigIntegerField()
        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()
    
        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)
        publishes = models.ForeignKey(to="Publish",)
        authors = models.ManyToManyField(to='Author',)
    
        def __str__(self):
            return self.title
    
        #id 不写,默认递增主键  __str__方法返回可读懂对象
    

    执行数据库同步指令

    python manage.py makemigrations
    python manage.py migrate
    

    创建admin超级用户

    python manage.py createsuperuser
    输入用户名:wuchao
    邮箱不用输 直接回车
    输入密码:必须超过8位,并且别太简单
    
    

    admin注册表结构

    from django.contrib import admin
    
    # Register your models here.
    
    from app01 import models
    
    admin.site.register(models.Author)
    admin.site.register(models.AuthorDetail)
    admin.site.register(models.Publish)
    admin.site.register(models.Book)
    

    查询逻辑

    showbook表

    models.Book.objects.all()     查询所有的书籍的queryset对象
    for循环得到model对象
    model 对象点字段得到具体的名称
    根据多表查询查到作者的对象,for循环得到model对象
    
    	# 已知书籍名,查询出版社,正向
        # obj = models.Book.objects.filter(title="大主宰").first()
        # ph = obj.publishes.name
    
        # 已知书籍名,查询作者,正向查询
        # obj = models.Book.objects.filter(title="万剑道尊").first()
        # ret = obj.authors.all() #<QuerySet [<Author: 邸宗超>, <Author: 韩星>, <Author: 李文宝>]>
        # for i in ret:
        #     print(i.name)
        #     print(i.au.telephone)  #连环查询,有对象,正向查询
        
        在前端html中生成多对多的作者名字有三种书写格式
        第一种  
        	  {% for author_obj in obj.authors.all %}
                {{ author_obj.name }}
                {% if forloop.last %}
                {% else %}
                ,
                {% endif %}
            {% endfor %}
            根据后端传的queryset对象循环得到model对象,再获得作者的queryset对象,后边的if判断是根据是否是最后一			个作者来判断谁否加逗号
        第二种方法 在models.py的book类中再创建一个方法后端的实例对象点方法就是调用
        #没有改变数据库相关字段,不用执行数据库同步指令
        def get_author_name(self):
            ret = self.authors.all()
            au_list = []
            for i in ret:
                i.append(i.name)
            return ",".join(au_list)
        
        前端改为 <td>{{ book_obj.get_author_name }}</td> 因为book_obj就是书籍的实例化对象
      第三种方法  	
    def get_author_name(self):
            return ",".join([i.name for i in self.authors.all()])
        列表推导时一次搞定
    

    添加书籍表

        if request.method == "GET":
            all_publish = models.Publish.objects.all()
            all_author = models.Author.objects.all()
            #分别后的出版社和作者的queryset对象
            return render(request,"addbook.html",{"all_publish":all_publish,"all_author":all_author})
    	else:
    	#post请求
    # authors = request.POST.get("authors")
        # get方法只能获得一个值
        authors = request.POST.getlist("authors")
        """
            print(authors) 根据前端的name属性取值
            ['1', '3'] 得到所有提交的作者id
            """
    
    data = request.POST.dict()
            """
            print(data)
            #{'csrfmiddlewaretoken': 'Opb8KW3rEZ4glfxwXZ8hmrxwRzINxNFYD8vWkDoCn0MY1YYZ67iR6j2VZl3tWkl6', 'title': '神马', 'price': '666.00', 'publishes_id': '2', 'publishDate': '2019-10-10', 'authors': '3'}
            """
            #request.POST.dict() 看authors数据,当有多个值时,得到最后一个
            #多对多时的数据出错
      但是第一个值和最后一个值没有在book字段中,根据字典的删除出去这两个字段
      data.pop("csrfmiddlewaretoken")
      data.pop("authors")
            """
            print(data)
            {'title': '神马', 'price': '666.00', 'publishes': '1', 'publishDate': '2019-10-03'}
            """
    new_book_obj = models.Book.objects.create(**data)
    new_book_obj.authors.add(*authors)
    分别添加书籍表和作者表相关数据
    return redirect("showbook")
    

    注意 book表添加数据时,前端的name属性时提交数据的,book表和出版社表关联存的数据存储时publishes对应对象,publishes_id 对应数字,而book表中没有作者的相关字段,在第三张表

    post的相关方法

    self.authors.all()   根据书籍的实例化对象获得作者所有的对象,后端all(),前端all 没有括号
    request.POST.get("authors")       根据属性获得一个值,没有是None
    request.POST.getlist("authors")   多对对关系中,获得所有提交的数据比如作者的所有提交的id
    
  • 相关阅读:
    LeetCode--Insert Interval
    LeetCode--Surrounded Regions
    LeetCode--Container With Most Water
    LeetCode--Permutation Sequence
    NYOJ---540奇怪的排序
    NYOJ-858下三角矩阵
    素数筛选法
    NYOJ----776删除元素
    矩阵快速幂
    神奇算式
  • 原文地址:https://www.cnblogs.com/lvweihe/p/11695409.html
Copyright © 2011-2022 走看看