图书多表操作相关笔记

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

猜你喜欢

转载自www.cnblogs.com/lvweihe/p/11695409.html