Compare commits

...

7 Commits

@ -1,14 +1,38 @@
from django import forms
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.forms import UsernameField
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.admin import UserAdmin # Django 自带的用户管理后台基类
from django.contrib.auth.forms import UserChangeForm # Django 默认的用户信息修改表单
from django.contrib.auth.forms import UsernameField # Django 用于用户名字段的专用表单字段
from django.utils.translation import gettext_lazy as _ # 用于支持多语言翻译的辅助函数
# Register your models here.
# 从当前 app 的 models 导入自定义的用户模型 BlogUser
from .models import BlogUser
# ======================
# 自定义用户创建表单(用于后台添加用户时使用)
# ======================
class BlogUserCreationForm(forms.ModelForm):
# 添加两个密码字段,用于用户注册时输入和确认密码
password1 = forms.CharField(
label=_('password'), # 字段显示名称可翻译这里是“password”
widget=forms.PasswordInput # 使用密码输入框,输入内容会被隐藏
)
password2 = forms.CharField(
label=_('Enter password again'), # 确认密码的标签
widget=forms.PasswordInput # 同样是密码输入框
)
class Meta:
model = BlogUser # 指定该表单关联的模型是 BlogUser
fields = ('email',) # 在创建用户时,只显示 email 字段(可以从后台选择的字段)
def clean_password2(self):
"""
校验两次输入的密码是否一致
"""
# 从 cleaned_data 中获取用户输入的两个密码
"""
自定义用户创建表单用于在Admin后台添加新用户
继承自ModelForm提供密码验证和哈希处理功能
@ -25,14 +49,36 @@ class BlogUserCreationForm(forms.ModelForm):
验证两次输入的密码是否一致
如果密码不匹配抛出验证错误
"""
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
# 如果两个密码都有值,但它们不相等,则抛出验证错误
if password1 and password2 and password1 != password2:
raise forms.ValidationError(_("passwords do not match"))
raise forms.ValidationError(_("passwords do not match")) # 提示“密码不匹配”
# 验证通过,返回 password2通常返回确认密码字段的值
return password2
def save(self, commit=True):
"""
<<<<<<< HEAD
保存用户对象并对密码进行哈希处理
"""
# 调用父类的 save 方法但不立即提交到数据库commit=False
user = super().save(commit=False)
# 对用户输入的密码password1进行哈希处理并设置到 user 对象上
user.set_password(self.cleaned_data["password1"])
if commit:
# 如果 commit=True默认则保存到数据库
# 同时,给用户添加一个来源标识 source = 'adminsite',表示是通过后台添加的
user.source = 'adminsite'
user.save()
# 返回保存后的用户对象
=======
保存用户信息对密码进行哈希处理
commit参数控制是否立即保存到数据库
"""
@ -41,15 +87,31 @@ class BlogUserCreationForm(forms.ModelForm):
if commit:
user.source = 'adminsite' # 标记用户来源为管理员后台
user.save() # 保存到数据库
>>>>>>> master
return user
# ======================
# 自定义用户修改表单(用于后台编辑用户信息时使用)
# ======================
class BlogUserChangeForm(UserChangeForm):
"""
自定义用户信息修改表单
继承自Django内置的UserChangeForm用于在Admin后台编辑用户信息
"""
class Meta:
<<<<<<< HEAD
model = BlogUser # 指定关联的模型是 BlogUser
fields = '__all__' # 表单中包含模型的所有字段
# 指定 username 字段使用 Django 提供的 UsernameField它对用户名有特殊处理如唯一性等
field_classes = {'username': UsernameField}
def __init__(self, *args, **kwargs):
"""
初始化方法这里暂时没有额外逻辑只是调用了父类的初始化
"""
super().__init__(*args, **kwargs)
=======
model = BlogUser
fields = '__all__' # 包含所有字段
field_classes = {'username': UsernameField} # 指定用户名字段的类型
@ -57,9 +119,38 @@ class BlogUserChangeForm(UserChangeForm):
def __init__(self, *args, **kwargs):
"""初始化方法,可以在这里添加自定义的表单逻辑"""
super().__init__(*args, **kwargs)
>>>>>>> master
# ======================
# 自定义用户管理后台类(用于在 Django Admin 中管理 BlogUser 模型)
# ======================
class BlogUserAdmin(UserAdmin):
<<<<<<< HEAD
# 指定用户修改时使用的表单类(编辑用户信息时)
form = BlogUserChangeForm
# 指定用户创建时使用的表单类(添加新用户时)
add_form = BlogUserCreationForm
# 定义在用户列表页显示哪些字段
list_display = (
'id', # 用户 ID
'nickname', # 昵称(假设你的 BlogUser 模型中有这个字段)
'username', # 用户名
'email', # 邮箱
'last_login', # 上次登录时间
'date_joined', # 注册时间
'source' # 用户来源(比如 adminsite 表示后台添加)
)
# 定义哪些字段可以作为链接,点击后可以进入编辑页面
# 这里 id 和 username 都可以作为链接
list_display_links = ('id', 'username')
# 定义默认排序方式,这里是按照 id 降序(最新的用户在前面)
ordering = ('-id',)
=======
"""
自定义用户管理类配置Admin后台的用户管理界面
继承自Django内置的UserAdmin类
@ -79,4 +170,5 @@ class BlogUserAdmin(UserAdmin):
)
list_display_links = ('id', 'username') # 可点击跳转到编辑页面的字段
ordering = ('-id',) # 按ID倒序排列最新的用户显示在最前面
ordering = ('-id',) # 按ID倒序排列最新的用户显示在最前面
>>>>>>> master

@ -1,50 +1,105 @@
user nginx;
# 声明使用Nginx服务配置文件起始标识
user nginx;
# 设置工作进程数量,"auto"表示自动根据CPU核心数调整优化并发处理能力
worker_processes auto;
# 错误日志配置:日志路径为/var/log/nginx/error.log日志级别为notice记录警告及以上级别信息
error_log /var/log/nginx/error.log notice;
# 进程ID文件路径存储Nginx主进程PID的文件用于进程管理如启动/停止服务)
pid /var/run/nginx.pid;
# 事件模块配置控制Nginx处理连接的方式
events {
# 每个工作进程的最大连接数并发处理能力上限默认1024可根据服务器性能调整
worker_connections 1024;
}
# HTTP核心模块配置处理HTTP协议的核心设置包含所有与HTTP请求相关的配置
http {
# 引入MIME类型映射文件定义不同文件扩展名对应的Content-Type如.html对应text/html
include /etc/nginx/mime.types;
# 默认MIME类型当无法识别文件类型时默认按二进制流application/octet-stream处理
default_type application/octet-stream;
# 定义日志格式,命名为"main"(后续可通过此名称引用该格式)
# 日志字段说明:
# $remote_addr客户端IP地址
# $remote_user客户端认证用户名未认证则为空
# [$time_local]:访问时间(本地时区)
# "$request"完整请求行如GET /index.html HTTP/1.1
# $statusHTTP响应状态码如200、404
# $body_bytes_sent发送给客户端的响应体大小字节
# "$http_referer"请求来源页面Referer头信息
# "$http_user_agent":客户端浏览器/设备信息User-Agent头
# "$http_x_forwarded_for"代理链中的客户端真实IP多代理场景下使用
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 访问日志配置:使用上述"main"格式,日志路径为/var/log/nginx/access.log
access_log /var/log/nginx/access.log main;
# 启用高效文件传输模式(通过内核缓冲区直接发送文件,减少用户态与内核态切换,提升性能)
sendfile on;
# 关闭tcp_nopush与sendfile配合使用开启时会累积数据再一起发送适合大文件此处关闭则实时发送
#tcp_nopush on;
# 长连接超时时间:客户端与服务器保持连接的最大时长(秒),超时后自动关闭连接
keepalive_timeout 65;
# 关闭gzip压缩若需启用取消注释并配置可压缩响应数据减少传输量
#gzip on;
# 虚拟主机配置定义一个具体的网站服务可配置多个server块实现多网站
server {
# 网站根目录默认请求的文件查找路径此处指向Django静态文件收集目录
root /code/djangoblog/collectedstatic/;
# 监听端口该虚拟主机监听80端口HTTP默认端口
listen 80;
# 该虚拟主机的长连接超时时间覆盖http块中的全局设置此处为70秒
keepalive_timeout 70;
# 静态文件路径配置:匹配以/static/开头的请求
location /static/ {
# 静态文件缓存策略:设置为最大缓存时间(浏览器会长期缓存,适合不常变化的静态资源)
expires max;
# 静态文件实际路径:将/static/请求映射到该目录与root的区别是会替换location路径
alias /code/djangoblog/collectedstatic/;
}
# 主请求处理:匹配所有其他路径的请求(除上述/static/外)
location / {
# 设置代理请求头传递客户端真实IP给后端服务
proxy_set_header X-Real-IP $remote_addr;
# 设置代理请求头传递代理链中的客户端IP列表多代理场景
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 设置代理请求头传递原始请求的Host头信息后端服务用于识别域名
proxy_set_header Host $http_host;
# 自定义代理标识头后端服务可通过此头判断请求来自Nginx代理
proxy_set_header X-NginX-Proxy true;
# 关闭代理重定向禁止Nginx自动修改后端服务返回的Location头
proxy_redirect off;
# 条件判断:如果请求的文件在本地不存在(!-f表示非文件
if (!-f $request_filename) {
# 反向代理将请求转发到名为djangoblog的服务的8000端口通常是Django的uWSGI/Gunicorn服务
proxy_pass http://djangoblog:8000;
break;
# 跳出当前if块不再执行后续逻辑
break;
}
}
}
}
}

@ -1,34 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<!-- 加载static静态文件标签用于后面引用静态资源 -->
{% load static %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<!-- 以上3个meta标签必须放在head的最前面 -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<!-- 禁止搜索引擎索引此页面 -->
<meta name="robots" content="noindex">
<!-- 动态设置页面标题使用Django模板变量 -->
<title>{{ SITE_NAME }} | {{ SITE_DESCRIPTION }}</title>
<!-- 加载账户相关的CSS文件 -->
<link href="{% static 'account/css/account.css' %}" rel="stylesheet">
<!-- 使用Django压缩工具压缩CSS文件 -->
{% load compress %}
{% compress css %}
<!-- Bootstrap core CSS -->
<!-- Bootstrap核心CSS文件 -->
<link href="{% static 'assets/css/bootstrap.min.css' %}" rel="stylesheet">
<!-- OAuth认证样式 -->
<link href="{% static 'blog/css/oauth_style.css' %}" rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<!-- IE10视口bug修复 -->
<link href="{% static 'assets/css/ie10-viewport-bug-workaround.css' %}" rel="stylesheet">
<!-- TODC Bootstrap core CSS -->
<!-- TODC Bootstrap样式 -->
<link href="{% static 'assets/css/todc-bootstrap.min.css' %}" rel="stylesheet">
<!-- Custom styles for this template -->
<!-- 登录页面自定义样式 -->
<link href="{% static 'assets/css/signin.css' %}" rel="stylesheet">
{% endcompress %}
<!-- 压缩JavaScript文件 -->
{% compress js %}
<!-- IE10视口bug修复脚本 -->
<script src="{% static 'assets/js/ie10-viewport-bug-workaround.js' %}"></script>
<!-- IE浏览器仿真模式警告 -->
<script src="{% static 'assets/js/ie-emulation-modes-warning.js' %}"></script>
{% endcompress %}
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- HTML5 shim和Respond.js用于IE8支持HTML5元素和媒体查询 -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
@ -36,12 +49,15 @@
</head>
<body>
{% block content %}
{% endblock %}
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<!-- 定义内容块,子模板可以在此处插入具体内容 -->
{% block content %}
{% endblock %}
<!-- IE10视口hack用于Surface/桌面Windows 8 bug -->
</body>
<!-- 引入jQuery库 -->
<script type="text/javascript" src="{% static 'blog/js/jquery-3.6.0.min.js' %}"></script>
<!-- 引入账户相关的JavaScript文件 -->
<script src="{% static 'account/js/account.js' %}" type="text/javascript"></script>
</html>
Loading…
Cancel
Save