要求:
① 页面写入超链接,获取所有数据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")) 
                


















