diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/DjangoBlog.iml b/.idea/DjangoBlog.iml new file mode 100644 index 0000000..829c823 --- /dev/null +++ b/.idea/DjangoBlog.iml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..913e951 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..243d127 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/doc/FastBlog演示视频.mp4 b/doc/FastBlog演示视频.mp4 new file mode 100644 index 0000000..8100944 Binary files /dev/null and b/doc/FastBlog演示视频.mp4 differ diff --git a/doc/开源软件泛读、标注和维护报告文档.docx b/doc/开源软件泛读、标注和维护报告文档.docx new file mode 100644 index 0000000..912457f Binary files /dev/null and b/doc/开源软件泛读、标注和维护报告文档.docx differ diff --git a/doc/开源软件泛读报告.docx b/doc/开源软件泛读报告.docx new file mode 100644 index 0000000..4cedfc0 Binary files /dev/null and b/doc/开源软件泛读报告.docx differ diff --git a/doc/开源软件的质量分析报告文档.docx b/doc/开源软件的质量分析报告文档.docx new file mode 100644 index 0000000..5f0e6cc Binary files /dev/null and b/doc/开源软件的质量分析报告文档.docx differ diff --git a/doc/编码规范.docx b/doc/编码规范.docx new file mode 100644 index 0000000..8b28df6 Binary files /dev/null and b/doc/编码规范.docx differ diff --git a/src/accounts/admin.py b/src/accounts/admin.py index 0495352..e77ec2b 100644 --- a/src/accounts/admin.py +++ b/src/accounts/admin.py @@ -62,22 +62,24 @@ class BlogUserChangeForm(UserChangeForm): # 自定义用户管理类,用于在Django管理后台管理用户 class BlogUserAdmin(UserAdmin): - # 指定修改用户信息时使用的表单 form = BlogUserChangeForm - # 指定创建用户时使用的表单 add_form = BlogUserCreationForm - # 定义在用户列表中显示的字段 list_display = ( - 'id', # 用户ID - 'nickname', # 昵称 - 'username', # 用户名 - 'email', # 邮箱 - 'last_login', # 上次登录时间 - 'date_joined', # 注册时间 - 'source') # 用户来源 - # 定义可以点击进入详情页面的字段 + 'id', + 'nickname', + 'username', + 'email', + 'last_login', + 'date_joined', + 'source' + ) list_display_links = ('id', 'username') - # 定义用户列表的排序方式 ordering = ('-id',) - # 定义搜索字段 - search_fields = ('username', 'nickname', 'email') \ No newline at end of file + search_fields = ('username', 'nickname', 'email') + + fieldsets = ( + (None, {'fields': ('username', 'password')}), + (_('Personal info'), {'fields': ('email', 'nickname')}), + (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), + (_('Important dates'), {'fields': ('last_login', 'date_joined')}), + ) \ No newline at end of file diff --git a/src/accounts/user_login_backend.py b/src/accounts/user_login_backend.py index ff0889d..749c24b 100644 --- a/src/accounts/user_login_backend.py +++ b/src/accounts/user_login_backend.py @@ -1,50 +1,18 @@ -from django.contrib.auth.models import AbstractUser +# filepath: f:\DjangoBlog\src\accounts\user_login_backend.py +from django.contrib.auth.backends import ModelBackend +from django.contrib.auth import get_user_model from django.db import models -from django.urls import reverse -from django.utils.timezone import now -from django.utils.translation import gettext_lazy as _ -from djangoblog.utils import get_current_site +User = get_user_model() - -# 创建自定义用户模型,继承自Django内置的AbstractUser -class BlogUser(AbstractUser): - # 用户昵称字段,存储用户的昵称,允许为空,最大长度为100字符 - nickname = models.CharField(_('nick name'), max_length=100, blank=True) - # 用户创建时间字段,记录用户的创建时间,默认为当前时间 - creation_time = models.DateTimeField(_('creation time'), default=now) - # 用户最后修改时间字段,记录用户信息的最后修改时间,默认为当前时间 - last_modify_time = models.DateTimeField(_('last modify time'), default=now) - # 用户来源字段,记录用户的创建来源(如管理后台、第三方登录等),允许为空,最大长度为100字符 - source = models.CharField(_('create source'), max_length=100, blank=True) - - def get_absolute_url(self): - """ - 获取用户的绝对URL,用于跳转到用户的详情页面。 - 例如:根据用户名生成用户详情页面的URL。 - """ - return reverse( - 'blog:author_detail', kwargs={ - 'author_name': self.username}) # 根据用户名生成URL - - def __str__(self): - """ - 定义对象的字符串表示,返回用户的邮箱地址。 - """ - return self.email - - def get_full_url(self): - """ - 获取用户的完整URL,包括域名和路径。 - 例如:https://example.com/author/ - """ - site = get_current_site().domain # 获取当前站点的域名 - url = "https://{site}{path}".format(site=site, - path=self.get_absolute_url()) # 拼接完整URL - return url - - class Meta: - # 定义模型的元数据 - ordering = ['-id'] # 默认按ID降序排列 - verbose_name = _('user') # 定义模型在管理后台中的单数名称 - verbose_name_plural = verbose_name # 定义模型在管理后台中的复数名称 - get_latest_by = 'id' # 指定获取最新记录时使用的字段为ID \ No newline at end of file +class EmailOrUsernameModelBackend(ModelBackend): + """ + 自定义认证后端,支持通过用户名或邮箱登录 + """ + def authenticate(self, request, username=None, password=None, **kwargs): + try: + # 尝试通过用户名或邮箱获取用户 + user = User.objects.get(models.Q(username=username) | models.Q(email=username)) + if user.check_password(password): + return user + except User.DoesNotExist: + return None \ No newline at end of file