雖然說好D29要開始網站的建置,但其實最近忙於實驗,也沒有特別去規劃,所以打算做一個預約系統,我預想可以用它來幫我預約實驗或讓訪客可以直接看到有實驗的時段。在這篇會用比較沒有修飾的方式,先做出功能,之後部署可能會在Medium或其他地方陸續更新。
那我們就來迎接30天的最後一步!
那其實在前幾天裡,就已經慢慢把頁面都建立起來了,今天我們就只要把他串起來即可
這部分之前有講過了,不過還是把程式碼貼出來,這樣會比較清楚。
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('reserve/', include('Django_app.urls')),
path('account/', include('django.contrib.auth.urls')),
path('login/',views.login, name = 'login'),
path('log_out',views.log_out, name= "log_out"),
path('main_page', views.main_page, name = 'main_page'),
path('sign_up/', views.SignUpView.as_view(), name = "sign_up")
]
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import TemplateView, CreateView
from django.urls import reverse, reverse_lazy
from django.contrib import auth
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
def login(request):
if request.user.is_authenticated:
return HttpResponseRedirect('/main_page')
username = request.POST.get('username')
password = request.POST.get('password')
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect('/main_page')
else:
return render(request, 'login.html', locals())
def main_page(request):
return render(request, 'main_page.html')
def log_out(request):
auth.logout(request)
return HttpResponseRedirect('/main_page')
class SignUpView(CreateView):
form_class = UserCreationForm
success_url = reverse_lazy('login')
template_name = 'sign_up.html'
<html>
<title>登入</title>
</head>
<body>
<h1>實驗預約系統</h1><br>
<div><form method="post" class="center">
{% csrf_token %}
<div><table class="center">
<tr>
<td width="16%" align="right">帳號:</td>
<td width="84%"><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td width="16%" align="right">密碼:</td>
<td width="84%"><input type="password" name="password" id = "password" ></td>
</tr>
<tr>
<div><td><p><input type="submit" name="login" value="登入"></p></td></div>
<div><td>
<p>
<button type="button">
<a href= "{% url 'main_page' %}">訪客登入</a>
</button>
</p>
</td></div>
<div><td><a href="{% url 'sign_up' %}">註冊</a></td></div>
</tr>
</table></div>
</form></div>
</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.0">
<title>Document</title>
</head>
<body>
<p>你已經登出囉!</p>
<a href= "{% url 'login' %}">回到登入頁面</a>
</body>
</html>
<h1>註冊頁面<h1>
<form method = "POST">
{% csrf_token %}
{{form.as_p}}
<input type= "submit", value = "註冊">
</form>
<!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.0">
<title>Document</title>
</head>
<body>
<h1>歡迎來到實驗預約系統!</h1>
{% if request.user.is_authenticated %}
<p>Hi~ {{request.user}} 您已經登入囉~!</p>
<a href= "{% url 'Order_System:order_list' %}">查看目前預約狀態</a><br>
<a href= "{% url 'Order_System:order' %}">預約</a><br>
<a href= "{% url 'log_out' %}">登出</a>
{% comment %} <a href= "{% url 'log_out' %}?next={{request.path}}">登出</a> {% endcomment %}
{% else %}
<p>您尚未登入唷~</p>
<a href= "{% url 'login' %}">回到登入頁面</a><br>
<a href= "{% url 'Order_System:order_list' %}">查看目前預約狀態</a>
{% comment %} a href= "{% url 'login' %}?next={{request.path}}">回到登入頁面</a> {% endcomment %}
{% endif %}
</body>
</html>
from django.urls import path
from . import views
app_name = 'Order_System'
urlpatterns = [
path('', views.OrderCreateView.as_view() , name = 'order'),
path('finish/', views.FinishView.as_view() , name = 'finish'),
path('orderlist/', views.OrderListView.as_view(), name = 'order_list'),
]
這裡有新增了一個外來鍵,要放的值是目前登入的使用者名稱,以這種方式可以區分不同帳號所預約的紀錄。
友善提醒:改完 model 要記得 migrate 唷!
from django.db import models
from datetime import datetime
from django.contrib.auth.models import User
from django.conf import settings
from django.utils import timezone
class account_info(models.Model):
account_name = models.CharField(max_length= 10)
account_email = models.EmailField()
account_order = models.DateField(default = datetime.now())
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE,primary_key=True)
class Meta:
db_table = 'account'
為了去抓目前登入的使用者並傳給 model,所以這裡使用了一個 form_valid() 的方法
form_valid 是 Model form 提供了的一個方法,可以自動儲存model資料。
我們可以用這個方式讓我們的外來鍵可以存取目前的使用者名稱。
from django.views.generic import TemplateView, CreateView, ListView, DetailView, UpdateView, DeleteView
from .models import account_info
from django.urls import reverse, reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.contrib.auth.models import User
class OrderCreateView(LoginRequiredMixin, CreateView):
# template_name = "Django_app/account_info.html"
login_url = "/login"
model = account_info
fields = ["account_name","account_email", "account_order"]
success_url = reverse_lazy("Order_System:finish")
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
class FinishView(TemplateView):
template_name = "Django_app/finish.html"
class OrderListView(ListView):
# model_list.html
model = account_info
#context_object_name = Order_list
# queryset = account_info.objects.all()
這裡的內容其實就是我們前天再講CBVs時所講的,也都幾乎沒有更改。
<!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.0">
<title>Document</title>
</head>
<body>
<form method="POST">
{% csrf_token %}
{% if request.user.is_authenticated %}
<p>Hi~ {{request.user}} 歡迎預約!</p>
{{form.as_p}}
{{created_by}}
<input type = "submit" value = "預約">
{% else %}
<p>您尚未登入唷~</p>
<a href= "{% url 'login' %}">回到登入頁面</a><br>
<a href= "{% url 'Order_System:order_list' %}">查看目前預約狀態</a>
{% endif %}
</form>
</body>
</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.0">
<title>Document</title>
</head>
<h1>預約資料表</h1>
<body>
<form method="POST">
{% for data in object_list %}
<li>預約人姓名:{{data.account_name}} 預約時間 {{data.account_order}} </li>
{% endfor %}
</form>
</body>
</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.0">
<title>Document</title>
</head>
<body>
<h1>預約完成!</h1>
<h2><a href = "{% url 'Order_System:order_list' %}">跳轉回紀錄頁面</h2>
</body>
</html>
這就是簡單的一個小網站了,請包涵介面非常醜,而且其實還有更新、刪除、功能跳轉列表等等很多功能可以做,礙於時間不夠,希望自己之後可以再慢慢更新XD
因為是在每天實驗的情況下來做這次挑戰,所以其實覺得每天都不太夠用XD,因為自己其實也是一邊查找資料和寫文章,還好我一開始好像屯了約5天的份量XDD,直到發現想講的內容變多以及有新東西以前沒用過後,開始覺得有一點壓力,因為都要先閱讀官方文件或影片,每天都寫到時間快到才發稿。不過回顧這30天,真是又充實又好玩,對 Django 的使用也更加了解,希望看了我的文章的大家也能稍微獲得一些東西!
最後期許自己能夠持續的精進自己,自己希望能夠以後至少能一週更新一篇文章啦XD
也非常感謝看到這裡的你,未來有機會也一定會繼續挑戰鐵人賽的!!
https://docs.djangoproject.com/en/4.1/topics/class-based-views/generic-editing/