1. 程式人生 > >ORM版學員管理系統

ORM版學員管理系統

nbsp sql standard rim exists byte utils creat ==

ORM版學員管理系統

班級表

表結構

class Class(models.Model):
    id = models.AutoField(primary_key=True)  # 主鍵
    cname = models.CharField(max_length=32)  # 班級名稱
    first_day = models.DateField()  # 開班時間

查詢班級

URL部分:

url(r^class_list/$, views.class_list, name="class_list"),

視圖部分:

def class_list(request):
    class_list 
= models.Class.objects.all() return render(request, "class_list.html", {"class_list": class_list})

HTML部分:

<table border="1">
  {% for class in class_list %}
    <tr>
    <td>{{ forloop.counter }}</td>
    <td>{{ class.id }}</td>
    <td>{{ class.cname }}</
td> <td>{{ class.first_day|date:‘Y-m-d‘ }}</td> </tr> {% endfor %} </table>

新增班級

URL部分:

url(r^add_class/$, views.add_class, name="add_class"),

視圖部分:

def add_class(request):
    # 前端POST填好的新班級信息
    if request.method == "POST":
        cname = request.POST.get("
cname") first_day = request.POST.get("first_day") # 還可以這麽獲取提交的數據,但不推薦這麽寫 # data = request.POST.dict() # del data["csrfmiddlewaretoken"] # 創建新數據的兩種方式 # new_class = models.Class(cname=cname, first_day=first_day) # new_class.save() models.Class.objects.create(cname=cname, first_day=first_day) # 跳轉到class_list return redirect(reverse(class_list)) # 返回添加班級的頁面 return render(request, "add_class.html")

HTML部分:

在班級列表頁面添加一個a標簽:

<a href="{% url ‘add_class‘ %}">新頁面添加</a>

新添加頁面:

註意 {% csrf_token %}date類型的input標簽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>添加班級</title>
</head>
<body>
<form action="{% url ‘add_class‘ %}" method="post">
  {% csrf_token %}
  <p>班級名稱:<input type="text" name="cname"></p>
  <p>開班日期:<input type="date" name="first_day"></p>
  <p>提交<input type="submit"></p>
</form>
</body>
</html>

刪除班級

URL部分:

url(r^delete_class/$, views.delete_class, name="delete_class"),

視圖部分:

def delete_class(request):
    class_id = request.GET.get("class_id")
    models.Class.objects.filter(id=class_id).delete()
    return redirect(reverse("class_list"))

HTML部分:

在班級列表頁面的表格中添加刪除。

<a href="{% url ‘delete_class‘ %}?class_id={{ class.id }}">刪除</a>

編輯班級

URL部分:

url(r^edit_class/$, views.edit_class, name="edit_class"),

視圖部分:

def edit_class(request):
    if request.method == "POST":
        class_id = request.POST.get("id")
        cname = request.POST.get("cname")
        first_day = request.POST.get("first_day")
        models.Class.objects.create(id=class_id, cname=cname, first_day=first_day)
        return redirect(reverse("class_list"))
    class_id = request.GET.get("class_id")
    class_obj = models.Class.objects.filter(id=class_id)
    if class_obj:
        class_obj = class_obj[0]
        return render(request, "edit_class.html", {"class": class_obj})
    # 找不到該條記錄
    else:
        return redirect(reverse("class_list"))

HTML部分:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>編輯班級</title>
</head>
<body>
<form action="{% url ‘edit_class‘ %}" method="post">
  {% csrf_token %}
  <input type="text" value="{{ class.id }}" style="display: none">
  <p>班級名稱:<input type="text" name="cname" value="{{ class.cname }}"></p>
  <p>開班日期:<input type="date" name="first_day" value="{{ class.first_day|date:‘Y-m-d‘ }}"></p>
  <p>提交<input type="submit"></p>
</form>
</body>
</html>

補充

如果將之前的URL由 /edit_class/?class_id=n修改為 /edit_class/n/ ,視圖函數和HTML部分分別應該如何修改?

URL部分:

url(r^edit_class/(\d+)$, views.edit_class, name="edit_class"),

視圖部分:

def edit_class(request, class_id):
    if request.method == "POST":
        cname = request.POST.get("cname")
        first_day = request.POST.get("first_day")
        models.Class.objects.create(id=class_id, cname=cname, first_day=first_day)
        return redirect(reverse("class_list"))

    class_obj = models.Class.objects.filter(id=class_id)
    if class_obj:
        class_obj = class_obj[0]
        return render(request, "edit_class.html", {"class": class_obj})
    # 找不到該條記錄
    else:
        print("沒有該班級")
        return redirect(reverse("class_list"))

HTML部分:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>編輯班級</title>
</head>
<body>
<form action="{% url ‘edit_class‘ class.id %}" method="post">
  {% csrf_token %}
  <input type="text" value="{{ class.id }}" style="display: none">
  <p>班級名稱:<input type="text" name="cname" value="{{ class.cname }}"></p>
  <p>開班日期:<input type="date" name="first_day" value="{{ class.first_day|date:‘Y-m-d‘ }}"></p>
  <p>提交<input type="submit"></p>
</form>
</body>
</html>

單表查詢API匯總

<1> all():                 查詢所有結果
 
<2> filter(**kwargs):      它包含了與所給篩選條件相匹配的對象
 
<3> get(**kwargs):         返回與所給篩選條件相匹配的對象,返回結果有且只有一個,如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
 
<4> exclude(**kwargs):     它包含了與所給篩選條件不匹配的對象
 
<5> values(*field):        返回一個ValueQuerySet——一個特殊的QuerySet,運行後得到的並不是一系列model的實例化對象,而是一個可叠代的字典序列
 
<6> values_list(*field):   它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列
 
<7> order_by(*field):      對查詢結果排序
 
<8> reverse():             對查詢結果反向排序
 
<9> distinct():            從返回結果中剔除重復紀錄
 
<10> count():              返回數據庫中匹配查詢(QuerySet)的對象數量。
 
<11> first():              返回第一條記錄
 
<12> last():               返回最後一條記錄
 
<13> exists():             如果QuerySet包含數據,就返回True,否則返回False

註意:一定區分Object與QuerySet的區別 !!!

QuerySet有update方法而Object默認沒有。

單表查詢之神奇的雙下劃線

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 獲取id大於1 且 小於10的值
 
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 獲取id等於11、22、33的數據
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 
models.Tb1.objects.filter(name__contains="ven")  # 獲取name字段包含"ven"的
models.Tb1.objects.filter(name__icontains="ven") # icontains大小寫不敏感
 
models.Tb1.objects.filter(id__range=[1, 3])      # id範圍是1到3的,等價於SQL的bettwen and
 
類似的還有:startswith,istartswith, endswith, iendswith 

date字段還可以:
models.Class.objects.filter(first_day__year=2017)

備註:

在Django的日誌設置中,配置上一個名為django.db.backends的logger實例即可查看翻譯後的SQL語句。

LOGGING = {
    version: 1,
    disable_existing_loggers: False,
    handlers: {
        console:{
            level:DEBUG,
            class:logging.StreamHandler,
        },
    },
    loggers: {
        django.db.backends: {
            handlers: [console],
            propagate: True,
            level:DEBUG,
        },
    }
}

Django項目完整版LOGGING配置:

技術分享圖片
LOGGING = {
    version: 1,
    disable_existing_loggers: False,
    formatters: {
        standard: {
            format: [%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]
                      [%(levelname)s][%(message)s]
        },
        simple: {
            format: [%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s
        },
        collect: {
            format: %(message)s
        }
    },
    filters: {
        require_debug_true: {
            (): django.utils.log.RequireDebugTrue,
        },
    },
    handlers: {
        console: {
            level: DEBUG,
            filters: [require_debug_true],  # 只有在Django debug為True時才在屏幕打印日誌
            class: logging.StreamHandler,
            formatter: simple
        },
        default: {
            level: INFO,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自動切
            filename: os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日誌文件
            maxBytes: 1024 * 1024 * 50,  # 日誌大小 50M
            backupCount: 3,
            formatter: standard,
            encoding: utf-8,
        },
        error: {
            level: ERROR,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自動切
            filename: os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日誌文件
            maxBytes: 1024 * 1024 * 50,  # 日誌大小 50M
            backupCount: 5,
            formatter: standard,
            encoding: utf-8,
        },
        collect: {
            level: INFO,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件,自動切
            filename: os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
            maxBytes: 1024 * 1024 * 50,  # 日誌大小 50M
            backupCount: 5,
            formatter: collect,
            encoding: "utf-8"
        }
    },
    loggers: {
       # 默認的logger應用如下配置
        ‘‘: {
            handlers: [default, console, error],  # 上線之後可以把‘console‘移除
            level: DEBUG,
            propagate: True,
        },
        # 名為 ‘collect‘的logger還單獨處理
        collect: {
            handlers: [console, collect],
            level: INFO,
        }
    },
}
Django項目常用LOGGING配置

ORM版學員管理系統