ORM版學院管理系統

ORM版學員管理系統

班級表

表結構html

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部分:django

複製代碼
<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部分:ide

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部分:oop

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

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

新添加頁面:ui

注意 {% csrf_token %}date類型的input標籤this

複製代碼
<!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等於十一、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配置
相關文章
相關標籤/搜索