圖書管理
書籍管理
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})
將數據庫修改之后報錯:刪掉1處,重新在新的數據庫插入數據
修改連接的數據庫
這里只是將斷開連接點的數據庫在pycharm上移除,而不是刪除后台數據庫
修改數據結構,再修改下代碼,就改成學員管理系統
演示級聯刪除:
級聯刪除成功:一對多,刪一,多中對應的都刪