要求:
① 页面写入超链接,获取所有数据item,显示在另一个页面,1min内,即使数据有变化,页面内容不变,1min后点击超链接可获取最新信息;
② 使用middleware完成用户请求路径判断 (request.path)。如果是“/schedule/select/”或“/select/contact/”,判断是否用户登录,否 则重定向到login页面。
①
结果:
代码:
python manage.py startapp pro6_app
注册app
path('pro6/', include('pro6_app.urls', namespace="pro6")),
views //
import datetime
from django.core.paginator import Paginator, InvalidPage
from django.shortcuts import render
from django.views.decorators.cache import cache_page
from djangoProject.settings import PAGE_SIZE
from pro6_app.models import Department
def home(request):
return render(request, "home.html")
@cache_page(60)
def show(request):
ds = Department.get_all()
page_num = request.GET.get("page_num", default=1)
paginator = Paginator(ds, PAGE_SIZE)
try:
data = paginator.page(page_num)
except InvalidPage:
data = paginator.page(1)
time = datetime.datetime.now()
return render(request, "show.html", {"data": data, "paginator": paginator, "time": time})
setting //
PAGE_SIZE = 3
urls //
from django.urls import path
from .views import *
app_name = "pro6"
urlpatterns = [
path('home/', home, name="home"),
path('show/', show, name="show"),
]
models //
# 迁移,添加测试数据
from django.db import models
class Department(models.Model):
name = models.CharField(max_length=64, verbose_name="科室")
month = models.CharField(max_length=2, verbose_name="月")
def __str__(self):
return f"{self.name}__{self.month}"
class Meta:
verbose_name = "安排表"
verbose_name_plural = verbose_name + 's'
@classmethod
def get_all(cls):
return cls.objects.all()
admin //
from django.contrib import admin
from pro6_app.models import Department
models = [
Department
]
admin.site.register(models)
templates //
<head>
<meta charset="UTF-8">
<title>home</title>
</head>
<body>
<a href="{% url 'pro6:show' %}">
<input type="button" value="Get data">
</a>
</body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Depars</title>
</head>
<body>
<table border="1" align="center" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>depar</th>
<th>month</th>
<th>year</th>
<th>remarks</th>
</tr>
</thead>
{% for i in data %}
<tr>
<td>{{ i.name }}</td>
<td>{{ i.month }}</td>
<td>2024</td>
<td>null</td>
</tr>
{% endfor %}
</table>
<center>
<a href="{% url 'pro6:show' %}?page_num=1" style="color:orangered">First</a>
{% if data.has_previous %}
<a href="{% url 'pro6:show' %}?page_num={{ data.previous_page_number }}" style="color:orangered">Previous</a>
{% else %}
<a href="javascript:alert('We are at the beginning.')">Previous</a>
{% endif %}
{{ data.number }}/{{ paginator.num_pages }}
{% if data.has_next %}
<a href="{% url 'pro6:show' %}?page_num={{ data.next_page_number }}" style="color:orangered">Next</a>
{% else %}
<a href="javascript:alert('Boundary of the void.')">Next</a>
{% endif %}
<a href="{% url 'pro6:show' %}?page_num={{ paginator.num_pages }}" style="color:orangered">Last</a>
</center>
<center>
<a href="{% url 'pro6:show' %}">
<input type="button" value="Refresh">
</a>
<hr>
<h6>Help with scheduling troubles.</h6>
<h6>Have a nice day.</h6>
<h6>{{ time|date:'H:i:s Y-m-d' }}. Shanghai, China, Asia.</h6>
</center>
</body>
</html>
②
结果:
1)未登录直接进入test页面的contact或select按钮,会跳转到登录页面
2)正常流程:注册成功→登录成功→test页面可select或contact(setting设置token过期时间是1day)
admin后台可见保存的加密后的token即pwd,没有保存用户原始密码。
代码:
(沿用上述pro6_app, 已注册)
models //
# admin 注册
class User(models.Model):
name = models.CharField(max_length=32, unique=True, verbose_name="Name")
pwd = models.CharField(max_length=128, verbose_name="Password")
token = models.CharField(max_length=128, null=True)
class Meta:
verbose_name = "网页用户"
verbose_name_plural = verbose_name + '们'
def __str__(self):
return self.name
@classmethod
def get_list(cls, **kwargs):
filters = {}
if kwargs.get("name"):
filters["name"] = kwargs.get("name")
if kwargs.get("pwd"):
filters["pwd"] = kwargs.get("pwd")
if kwargs.get("token"):
filters["token"] = kwargs.get("token")
return cls.objects.filter(**filters)
@classmethod
def create_one(cls, **kwargs):
return cls.objects.create(
name=kwargs.get("name"),
pwd=kwargs.get("pwd")
)
views //
# SESSION_COOKIE_AGE = 3600 * 24 # 60 * 60 * 24
def register(request):
if request.method == "GET":
return render(request, "pro6_regis.html")
if request.method == "POST":
name = request.POST.get("name")
pwd = hash(request.POST.get("pwd"))
User.create_one(**{"name": name, "pwd": pwd})
return redirect(reverse('pro6:login'))
def login(request):
if request.method == "GET":
return render(request, "pro6_login.html")
if request.method == "POST":
name = request.POST.get("name")
pwd = hash(request.POST.get("pwd"))
filters = {
"name": name,
"pwd": pwd
}
users = User.get_list(**filters)
if users:
user = users.first()
md5 = hashlib.md5()
md5.update(name.encode("utf-8"))
token = md5.hexdigest() + str(time.time())
user.token = token
user.save()
response = redirect(reverse('pro6:test'))
response.set_cookie("user_token", token)
return response
else:
return HttpResponse("<h5 style='color: orange'>Wrong Info..</h5>")
def test_view(request):
return render(request, "pro6_test.html")
def contact_view(request):
return HttpResponse("<h5 style='color:orange'>get in touch</h5>")
def select_view(request):
return HttpResponse("<h5 style='color:orange'>select it</h5>")
def del_user_token(request):
response = redirect(reverse('pro6:test'))
response.delete_cookie("user_token")
return response
templates //
register
<form action="" method="post">
{% csrf_token %}
UserName:<input type="text" name="name"> <br>
Password:<input type="password" name="pwd"> <br>
<input type="submit" value="Register">
</form>
login
<form action="" method="post">
{% csrf_token %}
UserName:<input type="text" name="name"> <br>
Password:<input type="password" name="pwd"> <br>
<input type="submit" value="Login">
</form>
test
<body>
<a href="{% url 'pro6:select' %}">select it</a>
<br>
<a href="{% url 'pro6:contact' %}">contact it</a>
<br>
<a href="{% url 'pro6:del' %}" style='color:purple' >delete user token</a>
</body>
urls //
path('regis/', register, name="regis"),
path('login/', login, name="login"),
path('test/', test_view, name="test"),
path('schedule/contact/', contact_view, name='contact'),
path('schedule/select/', select_view, name='select'),
path('del/', del_user_token, name='del'),
middleware //
# setting注册
class LoginMiddleWare(MiddlewareMixin):
def process_request(self, request):
target_path = [
'/pro6/schedule/select/',
'/pro6/schedule/contact/'
]
print(request.path)
if request.path in target_path:
print('in judge flag')
try:
user_token = request.COOKIES["user_token"]
users = User.get_list(token=user_token)
print('verified')
if not users:
return HttpResponse("Token expired.")
except:
return redirect(reverse("pro6:login"))