• Django图书管理系统(前端对有外键的数据表增删改查)


    图书管理

    书籍管理

    book

    name

    项目源码位置:https://gitee.com/machangwei-8/learning_materials/tree/master/%E9%A1%B9%E7%9B%AE/bookmanager02

    1、环境准备

     

    下载bootstrap

    引入到之前的网页:

    将下面的网页

    使用下面的模板 https://v3.bootcss.com/examples/dashboard/

    起步->基本模板->控制台

    刚刚我的复制过来有问题,settings配置静态文件目录配置错了,{},应该是[]。有文件但是没有渲染上,报错没找到文件,配置文件弄错了。

    将源码放到自己的文件中。将下面不要的删除

    下面的需要;

    圆圈不需要删掉:

    删掉:

    下面只留一个li标签

    现在删改并替换成这个样子了:

    将右下角的变成面板:使用如下样式:

     

    复制粘贴

    将下面的放到面板中

     格式化代码

    给它们是三个设置成按钮

    下面的地方修改一下:并且a标签的地址改正确

    下面的新增也改变一下,用刚才那个面板

    使用bootstrap

     使用栅栏

     选择下面的这个表单替换面板的内容:

    复制过来修改form  post请求,加个name,

     

    编辑页面也做一下,和添加页面差不多

    2、外键设计

    class Book(models.Model):
        title = models.CharField(max_length=32)
        pub = models.ForeignKey('Publisher', on_delete=models.CASCADE)

    on_delete 在django2.0 版本之后是必填的参数 1.11 之前的可以不填  

    on_delete 的参数 models.CASCADE models.SET() models.SET_DEFAULT models.SET_NULL

     

     一个出版社可以出版多本不同的书,一对多

    on_delete是级联删除用的。一对多,外键在多,

    级联   删一,多也删,删多,一不删;非级联删1多不删吧?

    外键Publisher不加引号也可以,但是必须方法Publisher类后面,然后是未定义。而这里支持字符串,是使用反射的方法,book类在前在后都可以

    on_delete 在django2.0 版本之后是必填的参数 1.11 之前的可以不填  

    on_delete 的参数 models.CASCADE models.SET() models.SET_DEFAULT models.SET_NULL

     

     还可以设置默认值,设置为空等等

    这里创建外键默认会在表中创建一个同名的加_id的字段。类中的这里代表的是外键的一行数据,一个对象

    orm一个类中设置了一个外键的类变量,这个类变量是外键所在类的一个对象(即外键所在类的一行数据的对象)。而在定义外键的这个类中,定义外键的那个字段是“外键类变量_id”来表示。

    既然这样,那我把models里字段改成pub。然后将刚刚的book删除

    删除之后重新生成迁移文件,迁移的时候出了问题:

    这是因为这里有之前的操作记录了,要删掉

    然后再执行显示表存在,再次删掉这张表

    修改成功:

    可以直接复制粘贴

     

    3、查询

    all_books = models.Book.objects.all()
    ​
    for book in all_books:
    ​
        print(book.title)
        print(book.pub,type(book.pub))   #  ——> 所关联的出版社对象
        print(book.pub.pk)  #  查id 多一次查询
        print(book.pub_id)  # 直接在book表中查出的ID
        print(book.pub.name)
        print("*"*32)

     现在做一个book_list的页面

    1)url,函数

    2)函数render一个book_list.html

    定义的外键是个对象,本表会加个_id(外键_id)作为本表的字段。引用外表的其它字段时,外键.外表字段

    因此这里可以:

    在本张表中,1和2的区别是1做了两次操作,先在本表拿到pub对象,再去另一张表中找到那张表的主键。而2只做了一次操作,所以2效率高

    三种方法如下:

    4、新增

    models.Book.objects.create(title=book_name,pub=出版社的对象)
    models.Book.objects.create(title=book_name,pub_id=pub_id)

    新增逻辑如下;

    这里没有东西:

    数据表字段写错了报错:应该是title   :          'name' is an invalid keyword argument for this function

    没获取到post传过来的值,赋值到数据库字段中是空的

    添加书籍成功:

     新建的这个对象,可以对象.字段进行取值了

    5、删除

    pk = request.GET.get('id')
    models.Book.objects.filter(pk=pk).delete()

     实现book_listt页面的删除按钮可以获取pk

     函数编写:

    我写的是小写book类名,数据库名字这里没有Book  #没有创建表的类或者类写错类名

    成功删除第一条带有外键(出版社)的数据:

    4处只匹配1,1后面有参数(2)是不用管的,在地址栏点击回车拼接出来的地址就能删除掉id是2的数据表记录 #地址栏做删除数据库操作,(如果用户有权限,那么数据库就可以被删数据)

    删除流程:服务器返回/book_list/的get请求结果

    6、编辑

    {% if book_obj.pub == publisher %}
        <option selected value="{{ publisher.pk }}"> {{ publisher.name }} </option>
    {% else %}
        <option  value="{{ publisher.pk }}"> {{ publisher.name }} </option>
    {% endif %}

    1)url,函数先实现返回编辑页面

    2)在book_list.html展示页中添加编辑按钮

    3)创建edit_book.html,和添加页面差不多。

    已经能拿到要编辑的pk,应该还要拿到要编辑的书名和出版社,以及其它可以通过下拉菜单做选择的其它选项

    显示编辑的书名:

    下拉选择菜单数据传进去:

     使用下面语法添加判断,满足条件的做另外的操作:

         {% if edit_obj %}
            {% else %}
            {% endif %}

    实现出版社默认显示要编辑的对象的:   判断从数据库拿到的每个出版社对象,如果==点击编辑的edit_obj这个对象,那么让它是被选中的

    编辑的逻辑过程;

     对象.字段=获取到的值  作为赋予新的值,就是编辑,点赋值需要save保存的,跟create创建有区别的。

    外键的重新赋值如下两种方式:

    7、修改数据,级联删除

    book_obj.title = book_name
    # book_obj.pub_id = pub_id
    book_obj.pub = models.Publisher.objects.get(pk=pub_id)
    book_obj.save()

     修改数据示例在上面的6、编辑数据中

    from django.shortcuts import render,redirect,HttpResponse
    from app01 import models
    #展示出版社
    def publisher_list(request):
        # 从数据库中查询到出版社的信息
        all_publishers = models.Publisher.objects.all().order_by('pk')
        return render(request, 'publisher_list.html', {'all_publishers': all_publishers}) #publisher_list.html中使用的是字典中的键,键代替这个所有的对象
    
    def add_publisher(request):
        error=''
        #返回一个包含from表单的出版社页面
        if request.method=='POST':
            publish_name=request.POST.get('publisher_name')
            # 判断出版社名称是否有重复的
            if models.Publisher.objects.filter(name=publish_name):
                error='出版社名称已存在'
            #判断输入值是否为空
            if not publish_name:
               error="输入不能为空"
            if not error:
                obj=models.Publisher.objects.create(name=publish_name)
                #跳转到展示出版社的页面
                return redirect('/publisher_list/')
        return render(request,'add_publisher.html',{'error':error})
    
    def del_publisher(request):
        # 获取要删除的数据
        pk = request.GET.get('id')
        obj_list = models.Publisher.objects.filter(pk=pk)
        if not obj_list:
            # 没有要删除的数据
            return HttpResponse('要删除的数据不存在')
        # 删除该数据
        # obj.delete()
        obj_list.delete()
        # 跳转到展示页面
        return redirect('/publisher_list/')
    
    def edit_publisher(request):
        error = ''  # 查找要编辑的数据
        pk = request.GET.get('id')  # url上携带的参数  不是GET请求提交参数
        obj_list = models.Publisher.objects.filter(pk=pk)
        if not obj_list:
            return HttpResponse('要编辑的数据不存在')
        obj = obj_list[0]
        if request.method == 'POST': # 处理POST请求
            publisher_name = request.POST.get('publisher_name')  # 获取新提交的出版的名称
            if models.Publisher.objects.filter(name=publisher_name):
                error = '新修改的名称已存在'  # 新修改的名称已存在
            if obj.name == publisher_name:
                error = '名称未修改'
            if not publisher_name:
                error = '名称不能为空'
            if not error:
                obj.name = publisher_name  # 修改数据
                obj.save()  # 保存数据到数据库中
                # 跳转到出版社的展示页面
                return redirect('/publisher_list/')
        return render(request, 'edit_publisher.html', {'obj': obj,'error':error})   # 返回一个包含原始数据的页面
    
    def book_list(request):
        books=models.book.objects.all()
        return render(request,'book_list.html',{'books':books})
    
    def add_book(request):
        if request.method=='POST':
            new_name=request.POST.get('new_name')
            pub_id=request.POST.get('pub')
            models.book.objects.create(title=new_name,pub_id=pub_id) #或者pub=models.Publisher.objects.get('pub_id')
            return redirect('/book_list/')
        publishers=models.Publisher.objects.all()
        return render(request,'add_book.html',{'publishers':publishers})
    
    def del_book(request):
        # 获取要删除的对象删除
        pk = request.GET.get('pk')
        models.book.objects.filter(pk=pk).delete() #删除要删除的对象
        # 跳转到展示页面
        return redirect('/book_list/')
    
    
    def edit_book(request):
        pk=request.GET.get('pk')
        edit_obj=models.book.objects.get(pk=pk)
        if  request.method == 'POST':
            new_name=request.POST.get('new_name')
            pub_id=request.POST.get('pub_id')
            edit_obj.title=new_name
            edit_obj.pub_id=pub_id
            edit_obj.save()
            return redirect('/book_list/')
        publishers=models.Publisher.objects.all()
        return render(request,'edit_book.html',{'edit_obj':edit_obj,'publishers':publishers})
    views.py

    将数据库修改之后报错:删掉1处,重新在新的数据库插入数据

     修改连接的数据库

    这里只是将断开连接点的数据库在pycharm上移除,而不是删除后台数据库

    修改数据结构,再修改下代码,就改成学员管理系统

    演示级联删除:

    级联删除成功:一对多,删一,多中对应的都删

  • 相关阅读:
    Vue学习计划基础笔记(五) 表单输入绑定、组件基础
    获取url参数,删除url参数,添加url参数
    Vue学习计划基础笔记(六) 组件基础
    js实现拦截粘贴并修改粘贴内容
    使用PHP写ajax接口
    Vue中使用函数防抖
    适用于Ant design的省市区联动JSON数据
    一个关于重绘与回流的BUG(动画后页面高度没撑开)
    js快速把字符串的'false'和'true'转换成Boolean布尔值的false和true
    js去掉对象或数组中的空值('',null,undefined,[],{})
  • 原文地址:https://www.cnblogs.com/machangwei-8/p/11023394.html
Copyright © 2020-2023  润新知