nch注释 #23

Merged
phm9gvnzi merged 2 commits from nch_branch into develop 4 months ago

@ -9,31 +9,63 @@ from blog.models import Article
# Create your models here.
class Comment(models.Model):
"""
评论模型类
用于存储博客文章的评论信息支持多级回复功能
"""
# 评论正文最大长度300字符在管理界面显示为'正文'
body = models.TextField('正文', max_length=300)
# 评论创建时间默认值为当前时间使用Django的国际化支持
creation_time = models.DateTimeField(_('creation time'), default=now)
# 评论最后修改时间,默认值为当前时间
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
# 评论作者,关联用户模型,删除用户时级联删除其所有评论
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_('author'),
on_delete=models.CASCADE)
# 所属文章,关联文章模型,删除文章时级联删除所有相关评论
article = models.ForeignKey(
Article,
verbose_name=_('article'),
on_delete=models.CASCADE)
# 父级评论,支持评论回复功能,允许为空表示顶级评论
parent_comment = models.ForeignKey(
'self',
'self', # 自关联,指向同一个模型
verbose_name=_('parent comment'),
blank=True,
null=True,
on_delete=models.CASCADE)
blank=True, # 在表单中允许为空
null=True, # 在数据库中允许为NULL
on_delete=models.CASCADE) # 删除父评论时级联删除子评论
# 评论是否启用(审核通过),默认未启用,不允许为空
is_enable = models.BooleanField(_('enable'),
default=False, blank=False, null=False)
class Meta:
"""
模型的元数据配置
"""
# 按ID降序排列新的评论显示在前面
ordering = ['-id']
# 单数名称,在管理界面显示
verbose_name = _('comment')
# 复数名称,与单数相同
verbose_name_plural = verbose_name
# 指定获取最新记录时使用的字段
get_latest_by = 'id'
def __str__(self):
return self.body
"""
对象的字符串表示方法
在Django管理界面和其他显示对象的地方使用
"""
return self.body # 直接返回评论正文作为显示内容

@ -5,50 +5,93 @@ from django.contrib import admin
from django.urls import reverse
from django.utils.html import format_html
# 获取当前模块的日志记录器
logger = logging.getLogger(__name__)
class OAuthUserAdmin(admin.ModelAdmin):
"""
OAuth用户管理后台配置类
用于自定义Django Admin中OAuth用户模型的显示和行为
"""
# 搜索字段配置,支持按昵称和邮箱搜索
search_fields = ('nickname', 'email')
# 每页显示的项目数量
list_per_page = 20
# 列表页显示的字段
list_display = (
'id',
'nickname',
'link_to_usermodel',
'show_user_image',
'type',
'link_to_usermodel', # 自定义方法:链接到用户模型
'show_user_image', # 自定义方法:显示用户头像
'type', # OAuth类型
'email',
)
# 可点击进入编辑页的字段
list_display_links = ('id', 'nickname')
# 右侧筛选器配置
list_filter = ('author', 'type',)
# 只读字段列表(初始为空)
readonly_fields = []
def get_readonly_fields(self, request, obj=None):
"""
动态获取只读字段
将所有模型字段和多对多字段设为只读
"""
return list(self.readonly_fields) + \
[field.name for field in obj._meta.fields] + \
[field.name for field in obj._meta.many_to_many]
[field.name for field in obj._meta.fields] + \
[field.name for field in obj._meta.many_to_many]
def has_add_permission(self, request):
"""
禁用添加权限
OAuth用户应该通过OAuth流程自动创建而不是手动添加
"""
return False
def link_to_usermodel(self, obj):
"""
自定义方法生成指向关联用户模型的链接
"""
if obj.author:
# 获取用户模型的app和模型名称信息
info = (obj.author._meta.app_label, obj.author._meta.model_name)
# 生成用户编辑页面的URL
link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,))
# 返回HTML格式的链接
return format_html(
u'<a href="%s">%s</a>' %
(link, obj.author.nickname if obj.author.nickname else obj.author.email))
def show_user_image(self, obj):
img = obj.picture
"""
自定义方法在管理后台显示用户头像
"""
img = obj.picture # 获取头像图片URL
return format_html(
u'<img src="%s" style="width:50px;height:50px"></img>' %
(img))
# 设置自定义方法在管理后台的显示名称
link_to_usermodel.short_description = '用户'
show_user_image.short_description = '用户头像'
class OAuthConfigAdmin(admin.ModelAdmin):
"""
OAuth配置管理后台配置类
用于管理不同OAuth服务的配置信息
"""
# 列表页显示的字段
list_display = ('type', 'appkey', 'appsecret', 'is_enable')
# 右侧筛选器配置
list_filter = ('type',)

@ -2,4 +2,14 @@ from django.apps import AppConfig
class OauthConfig(AppConfig):
name = 'oauth'
"""
OAuth应用配置类
用于配置Django中OAuth应用的元数据和启动行为
这个类继承自Django的AppConfig基类用于定义
OAuth应用在Django项目中的配置信息
"""
# 指定应用的Python路径Django使用这个名称来识别应用
# 这应该与应用目录的名称保持一致
name = 'oauth'

@ -3,10 +3,32 @@ from django.forms import widgets
class RequireEmailForm(forms.Form):
"""
邮箱验证表单类
用于在OAuth登录过程中要求用户提供邮箱地址
通常在第三方OAuth服务没有返回邮箱信息时使用
"""
# 邮箱字段,标签显示为'电子邮箱',必填字段
email = forms.EmailField(label='电子邮箱', required=True)
# OAuth用户ID隐藏字段用于关联OAuth用户记录
oauthid = forms.IntegerField(widget=forms.HiddenInput, required=False)
def __init__(self, *args, **kwargs):
"""
初始化方法自定义表单字段的显示属性
Args:
*args: 位置参数
**kwargs: 关键字参数
"""
# 调用父类的初始化方法
super(RequireEmailForm, self).__init__(*args, **kwargs)
# 自定义邮箱字段的输入控件添加占位符和CSS类
self.fields['email'].widget = widgets.EmailInput(
attrs={'placeholder': "email", "class": "form-control"})
attrs={
'placeholder': "email", # 输入框内的提示文字
"class": "form-control" # Bootstrap样式类
})

@ -7,61 +7,113 @@ from django.utils.translation import gettext_lazy as _
class OAuthUser(models.Model):
"""
OAuth用户模型
用于存储通过第三方OAuth服务登录的用户信息
"""
# 关联到系统的本地用户允许为空初次OAuth登录时可能还未关联
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_('author'),
blank=True,
null=True,
on_delete=models.CASCADE)
on_delete=models.CASCADE) # 删除用户时级联删除OAuth记录
# OAuth服务提供的用户唯一标识
openid = models.CharField(max_length=50)
# 用户在第三方平台的昵称
nickname = models.CharField(max_length=50, verbose_name=_('nick name'))
# OAuth访问令牌用于后续API调用
token = models.CharField(max_length=150, null=True, blank=True)
# 用户在第三方平台的头像URL
picture = models.CharField(max_length=350, blank=True, null=True)
# OAuth服务类型如github、weibo等
type = models.CharField(blank=False, null=False, max_length=50)
# 用户在第三方平台的邮箱
email = models.CharField(max_length=50, null=True, blank=True)
# 存储额外的OAuth返回数据JSON格式
metadata = models.TextField(null=True, blank=True)
# 记录创建时间
creation_time = models.DateTimeField(_('creation time'), default=now)
# 最后修改时间
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
def __str__(self):
"""返回对象的字符串表示,显示用户昵称"""
return self.nickname
class Meta:
verbose_name = _('oauth user')
verbose_name_plural = verbose_name
ordering = ['-creation_time']
"""模型元数据配置"""
verbose_name = _('oauth user') # 单数名称
verbose_name_plural = verbose_name # 复数名称
ordering = ['-creation_time'] # 按创建时间降序排列
class OAuthConfig(models.Model):
"""
OAuth服务配置模型
用于存储不同OAuth服务的应用配置信息
"""
# OAuth服务类型选择项
TYPE = (
('weibo', _('weibo')),
('google', _('google')),
('github', 'GitHub'),
('facebook', 'FaceBook'),
('qq', 'QQ'),
('weibo', _('weibo')), # 微博
('google', _('google')), # 谷歌
('github', 'GitHub'), # GitHub
('facebook', 'FaceBook'), # Facebook
('qq', 'QQ'), # QQ
)
# OAuth服务类型从预定义选项中选择
type = models.CharField(_('type'), max_length=10, choices=TYPE, default='a')
# OAuth应用的AppKey/Client ID
appkey = models.CharField(max_length=200, verbose_name='AppKey')
# OAuth应用的AppSecret/Client Secret
appsecret = models.CharField(max_length=200, verbose_name='AppSecret')
# OAuth回调URL
callback_url = models.CharField(
max_length=200,
verbose_name=_('callback url'),
blank=False,
default='')
# 是否启用该OAuth服务
is_enable = models.BooleanField(
_('is enable'), default=True, blank=False, null=False)
# 配置创建时间
creation_time = models.DateTimeField(_('creation time'), default=now)
# 配置最后修改时间
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
def clean(self):
"""
数据验证方法
确保同类型的OAuth配置只能有一个
"""
if OAuthConfig.objects.filter(
type=self.type).exclude(id=self.id).count():
raise ValidationError(_(self.type + _('already exists')))
def __str__(self):
"""返回对象的字符串表示显示OAuth服务类型"""
return self.type
class Meta:
verbose_name = 'oauth配置'
verbose_name_plural = verbose_name
ordering = ['-creation_time']
"""模型元数据配置"""
verbose_name = 'oauth配置' # 单数名称(中文)
verbose_name_plural = verbose_name # 复数名称
ordering = ['-creation_time'] # 按创建时间降序排列
Loading…
Cancel
Save