Django圖書管理系統(前端對數據庫的增刪改查)

 

 

圖書管理系統html

出版社的管理前端

 源碼位置:https://gitee.com/machangwei-8/learning_materials/tree/master/%E9%A1%B9%E7%9B%AE/bookmanagermysql

1.設計URL

urlpatterns = [
  url(r'^publisher_list/', views.publisher_list),
]

1.1環境準備

建立項目bookmanager。app名字修改爲對應的。git

settingssql

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #項目目錄
DEBUG = True  #debug模式,測試的時候使用true

 建立數據庫: create database bookmanager;數據庫

 

#settings.py設置數據庫配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bookmanager',
        'HOST':'127.0.0.1',
        'PORT':3306,
        'USER':'root',
        'PASSWORD':'123',
    }
}

#init中使用pymysql
import pymysql
pymysql.install_as_MySQLdb()

#models.py中建立表
from django.db import models

# Create your models here.
class Publisher(models.Model):
    pid=models.AutoField(primary_key=True) #修改主鍵名字,使用本身建立的主鍵
    name=models.CharField(max_length=32)

 剛剛配置將USER配置成了USR,致使執行makegrations報錯:django

遷移文件生成:後端

遷移文件中生成表名,字段名等:瀏覽器

再添加一個字段。它提示添加個默認值或者退出:app

退出後,添加默認值再操做,添加字段,出錯

最終執行的遷移文件是這個內容,我再這裏面添加一下這個字段:

而後再models裏面添加這個,至關於一開始就在models里加了這個字段而後執行了makegragions。這樣表裏的內容和遷移文件對應上了。

彷佛執行改變了一次就生成一個文件:

剛纔出問題了,將這些刪掉,再執行試試。

生成數據庫表:

添加並上傳:

展現出版社,設置url

from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^publisher_list/', views.publisher_list),
]
def publisher_list(request):
    #顯示一個含出版社信息的頁面
    return render(request,'publisher_list.html')
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>魔降風雲變</title>
</head>
<body>
    <h1>出版社列表</h1>
</body>
</html>
publisher_list.html

這樣就拿到頁面了,可是還要展現出數據庫中的數據。

渲染數據庫的數據,將數據以表格形式顯示出來:

from app01 import models
#展現出版社
def publisher_list(request):
    # 從數據庫中查詢到出版社的信息
    all_publishers = models.Publisher.objects.all()
    return render(request, 'publisher_list.html', {'all_publishers': all_publishers}) #publisher_list.html中使用的是字典中的鍵,鍵代替這個全部的對象
#render方法也能夠傳{鍵值對},在html模板文件中使用鍵對傳入的值進行操做。

HTML頁面咱們能夠寫死了,可是咱們須要的是根據數據庫的內容展現出來,用模板渲染出來。

在函數中傳進來的是對象列表。每個都是對象,是表中一行數據:

每行數據庫的內容顯示在網頁,使用pk,那麼不管主鍵是啥名字,均可以用pk代替

給表格加個邊框:

添加序號列:forloop.counter,從字典中每循環一次就計數一次,這樣就讓每行內容有個序號。而咱們只須要將模板變量傳進去,用固定語法操做。

2.寫函數

from django.shortcuts import render
from app01 import models

# 展現出版社
def publisher_list(request):
  # 從數據庫中查詢到出版社的信息
  all_publishers = models.Publisher.objects.all()
  # 返回一個包含出版社信息的頁面
  return render(request, 'publisher_list.html', {'all_publishers': all_publishers})

 過程放在1裏面了

3.寫模板

<table border="1">
    <thead>
    <tr>
        <th>序號</th>
        <th>ID</th>
        <th>名稱</th>
    </tr>
    </thead>
    <tbody>

    {% for publisher in all_publishers %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ publisher.pk }}</td>
            <td>{{ publisher.name }}</td>
        </tr>
    {% endfor %}

    </tbody>
</table>

 過程放在1裏面了

 

3.一、新增

obj = models.Publisher.objects.create(name=publisher_name)

 新增功能的效果:出版社列表頁面中一個按鈕,點擊跳轉頁面。這個頁面中輸入出版社的相關信息(出版社名稱),有個按鈕提交信息,後臺要把輸入的信息插入到數據庫當中。插入以後瀏覽器須要再跳轉到出版社列表頁面。

這個按鈕直接是個a標籤就能夠。也就是我在出版社列表中有個a標籤,點擊跳轉頁面add_publisher,裏面要有form表單。

添加url,點擊views跳轉進入寫函數:

寫出添加數據庫記錄的頁面:這樣在框中輸入數據,後臺將數據獲取到並寫入數據庫中

 

 2處理的原理以下1處:

 獲取出版社的名稱:是獲取這個提交請求的name,得到post請求鍵值對中的值

# 使用ORM將數據插入到數據庫中,將獲取到的要添加的出版社名稱建立一個字段是輸入名稱的數據表記錄。pid不用寫,由於是自增

1處的請求2處沒有獲取到,而後後面的name=None,這樣前端3處跳轉報錯(1048, "Column 'name' cannot be null")

 上面的報錯的緣由是1處get的名字與2處不一致,全部沒有獲取到post提交的值,那麼1處的變量就是None。解決方法,將它們改成一致,我將模板文件的2處改成publisher_name。

下面我作的操做是在3處寫入‘小馬出版社’,點擊提交以後,5處不變,從新進入模板文件的頁面。可看函數,函數中不管GET或者POST請求都是返回的一樣的頁面。而後再看

4處數據庫,函數拿到了咱們提交的數據並在數據庫中已經建立了這條記錄。

網頁提交‘小馬過河2出版社’,建立一條數據,返回的是這個類的對象,就是那個數據表的一條記錄。能夠經過建立一行數據時的返回值取出這行數據的各個字段的內容。

咱們須要的是當咱們從添加出版社的頁面提交添加以後,那麼頁面跳轉查看全部出版社的頁面,這樣能看到新添加的出版社。那麼使用重定向:

看下圖,在add_publisher頁面中添加進一行數據後,直接跳轉到publisher_list頁面並顯示新添加的一條記錄‘小熊出版社’。

添加數據頁面能夠經過添加後進入展現全部數據的頁面,可是展現表中全部記錄的頁面尚未進入添加數據的頁面,那麼在展現表中全部記錄的頁面添加一個a標籤讓它跳轉到新增數據的頁面便可,以下圖

此處的a標籤地址應寫成路徑,在url路由中能找到,這裏實現了點擊新增進入添加數據的頁面,添加數據又能返回這裏的展現頁面。新增a標籤的跳轉其實是點擊以後又發送了一次get請求。

我如今添加一個重複的出版社名稱,它會添加記錄到數據庫中, 

出版社名字不該該重複的,下面就把這個字段設置成惟一鍵,而後執行數據遷移的那兩條命令結果報錯,緣由是數據庫中已經有重複的數據了‘小熊出版社’。

django.db.utils.IntegrityError: (1062, "Duplicate entry '小熊出版社' for key 'app01_publisher_name_36f04192_uniq'")

pycharm中將這條數據刪除掉並提交

而後執行那兩條數據遷移的命令,成功修改這個字段爲惟一鍵:

既然這個字段已是惟一鍵了,那麼我在頁面添加數據庫中已經有的這個字段內容,那麼報錯以下:

(1062, "Duplicate entry '小熊出版社' for key 'app01_publisher_name_36f04192_uniq'")

數據庫有約束,我應該在數據庫插入以前,就進行判斷有沒有這個數據,而不是直接就往數據裏面插入數據

這裏添加了判斷條件以後仍是報錯頁面,緣由是,咱們應該在數據插入以前就判斷是否存在相同的字段內容

 1處插入數據前判斷是否有相同的,有就傳進error信息到,而後在返回的原網頁後面渲染上錯誤提示信息(2處)。這樣同名的數據插入網頁會提示已存在的提示

若是我不寫內容直接點擊提交

出現了一條空數據,這顯然不是咱們想要的,全部咱們須要在這個的函數上作判斷,若是獲取的值爲空,那麼返回這個頁面,並在輸入框後面渲染不能輸入爲空的錯誤提示

 這裏顯示爲已存在,剛剛我在裏面插入了一個空的數據,如今將它刪除掉

如今顯示的是不能爲空了,一開始error不是這個信息,到了不能爲空這裏,又被覆蓋了一次。

看下面的代碼,有三個render

我想要將三個render簡化成一個:

1)我能夠最後返回一個render,其它的只是賦值error變量。而後render的頁面裏渲染不一樣的error值。若是沒有錯誤即默認error是空字符串就能夠。

2)而後判斷error信息是否非假(即非空),非假才執行建立數據記錄的操做並重定向頁面到查看全部出版社數據信息的頁面

當設置了一個error是空字符串的時候,正常返回的頁面是沒有顯示內容的。這樣雖然函數的結構修改了,可是功能沒有改變

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})
add_publisher

可是仍是有個問題,就是取出來的數據id是亂序的

 這是由於publiser_list這一頁的get請求出來的數據沒有排序,將從數據庫中取出來的全部數據給個排序就解決了

 

3.二、刪除

obj_list = models.Publisher.objects.filter(pk=pk)
obj_list.delete()

obj = models.Publisher.objects.get(pk=pk)
obj.delete()

 想要刪除某一條記錄,應該作什麼樣的操做呢?那麼在名稱列後面有個按鈕或者a標籤,點擊它就刪除掉這條記錄,這樣是能夠的吧。

那麼在展現頁中後面添加一列,使用a標籤

如今應該是我點擊一個刪除,而後發送一個請求 ,並在後端數據庫將這條數據刪除,刪除以後再跳轉到這個頁面

先設計刪除url,建立刪除函數,刪除函數邏輯以下;

若是個人函數中有一處存在錯誤,可能全部函數對應的網頁都不能訪問:檢查元素加載失敗

給刪除a標籤設置一個地址,已經實現點擊刪除訪問這個路徑了

可是點擊刪除的是哪條記錄,我須要獲取到才能在後臺將這條記錄刪除掉。因而將它的跳轉路徑拼接一個這條記錄的主鍵id

 刪除代碼:

點擊刪除:

 這時候我是點擊刪除按鈕刪的,我也可能使用瀏覽器訪問地址進行刪除

 

id=15的已刪除:

若是本身拼接在瀏覽器地址欄訪問請求不存在的記錄:報錯:Publisher matching query does not exist.

那麼我應該對這種狀況作個判斷,由於是get獲取數據的,get不到就會顯示錯誤,那麼將get改成過濾

過濾出來可能多條記錄,也能夠對queryset 這個對象列表裏的對象批量刪除

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/')
刪除功能代碼

 

3.三、編輯(修改數據)

obj.name = publisher_name
obj.save() # 保存數據到數據庫中

想要進行編輯的話應該是什麼樣的過程。點擊編輯a標籤以後能夠跳轉到編輯頁面,這個編輯頁面包含了你要編輯的那條數據,直接在這上面進行修改,修改完了以後提交,後臺修改了以後跳轉回來到全部出版社展現頁

建立url,建立函數,將編輯標籤和刪除標籤寫在同一列

點擊其中一個頁面往這個地址發送請求了,而且根據id獲取到了是哪條數據須要編輯

應該返回一個頁面,這個頁面中包含點擊編輯的那條原始數據。編輯頁面和添加頁面差很少。

 編輯的頁面這樣的話麼有帶上id=2這條數據的name

由於編輯按鈕a標籤跳轉的時候帶着對應數據的id,那麼由此得到這條數據並將它的內容name默認填入到編輯的input標籤裏

經過點擊編輯按鈕傳到請求裏的id查出知足條件的數據庫記錄,並傳到html模板文件中進行調用其中的值進行渲染。使得編輯框裏顯示要編輯的原數據內容

 

如圖,點擊這個id的就顯示出來要編輯的原數據。編輯的展現這樣就沒有問題

下面點擊提交,要進行如下的邏輯操做:

要修改id=2的數據:因爲發送POST請求以前,也要獲取到obj對象,全部把POST請求處理放在後面

 如今須要將可能遇到的問題寫上。傳進錯誤信息進行渲染

寫這些功能先寫正常的狀況下,而後再考慮會出現的問題。

四、項目目錄結構

 

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}) 


# 新增出版社
def add_publisher(request):
    # 對請求方式進行判斷
    if request.method == 'POST':
        # 處理POST請求
        # 獲取到出版社的名稱
        publisher_name = request.POST.get('publisher_name')
        # 判斷出版社名稱是否有重複的
        if models.Publisher.objects.filter(name=publisher_name):
            return render(request, 'add_publisher.html', {'error': '出版社名稱已存在'})
        # 判斷輸入的值是否爲空
        if not publisher_name:
            return render(request, 'add_publisher.html', {'error': '不能輸入爲空'})
        # 使用ORM將數據插入到數據庫中
        obj = models.Publisher.objects.create(name=publisher_name)
        # 跳轉到展現出版社的頁面
        return redirect('/publisher_list/')
    # 返回一個包含form表單的頁面
    return render(request, 'add_publisher.html')


# 新增出版社
def add_publisher(request):
    error = ''
    # 對請求方式進行判斷
    if request.method == 'POST':
        # 處理POST請求
        # 獲取到出版社的名稱
        publisher_name = request.POST.get('publisher_name')
        # 判斷出版社名稱是否有重複的
        if models.Publisher.objects.filter(name=publisher_name):
            error = '出版社名稱已存在'
        # 判斷輸入的值是否爲空
        if not publisher_name:
            error = '不能輸入爲空'
        if not error:
            # 使用ORM將數據插入到數據庫中
            obj = models.Publisher.objects.create(name=publisher_name)
            # 跳轉到展現出版社的頁面
            return redirect('/publisher_list/')
    # 返回一個包含form表單的頁面
    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})
參考代碼views
相關文章
相關標籤/搜索