From 782986aa14b882927f2e9561c49766efed529f89 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Tue, 4 Mar 2025 11:41:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/admin.py | 11 ++++++- account/api.py | 21 +++++++++++-- account/migrations/0003_user_raw_password.py | 18 +++++++++++ ...alter_user_raw_password_alter_user_role.py | 23 ++++++++++++++ .../0005_alter_user_raw_password.py | 18 +++++++++++ account/models.py | 12 +++++++ account/schemas.py | 31 +++++++++++++++++-- api/settings.py | 8 +++-- challenge/__init__.py | 0 challenge/admin.py | 3 ++ challenge/apps.py | 6 ++++ challenge/migrations/__init__.py | 0 challenge/models.py | 3 ++ challenge/views.py | 3 ++ 14 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 account/migrations/0003_user_raw_password.py create mode 100644 account/migrations/0004_alter_user_raw_password_alter_user_role.py create mode 100644 account/migrations/0005_alter_user_raw_password.py create mode 100644 challenge/__init__.py create mode 100644 challenge/admin.py create mode 100644 challenge/apps.py create mode 100644 challenge/migrations/__init__.py create mode 100644 challenge/models.py create mode 100644 challenge/views.py diff --git a/account/admin.py b/account/admin.py index c4a654c..d8a821f 100644 --- a/account/admin.py +++ b/account/admin.py @@ -1,4 +1,13 @@ from django.contrib import admin +from django.contrib.auth.admin import UserAdmin from .models import User -admin.site.register(User) + +class AdminUser(UserAdmin): + fieldsets = ((None, {"fields": ("username", "password", "role", "is_active")}),) + list_display = ("username", "role", "is_active") + list_filter = ("role", "is_active") + search_fields = ("username",) + + +admin.site.register(User, AdminUser) diff --git a/account/api.py b/account/api.py index 8971192..8a98c37 100644 --- a/account/api.py +++ b/account/api.py @@ -1,9 +1,11 @@ +from typing import List, Optional from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from ninja import Router from ninja.errors import HttpError -from .schemas import UserRegistrationSchema, UserLoginSchema +from .schemas import UserListSchema, UserRegistrationSchema, UserLoginSchema from .models import RoleChoices, User +from .decorators import super_required router = Router() @@ -38,8 +40,23 @@ def user_logout(request): @router.get("/profile") def my_profile(request): - # 暂时这样写 + # 首页获取用户状态 if request.user.is_authenticated: return {"username": request.user.get_username(), "role": request.user.role} else: return {"username": "", "role": RoleChoices.NORMAL} + + +@router.get("/list", response=List[UserListSchema]) +@super_required +def list(request, username: str): + # 之后加上分页 + users = User.objects.filter(username__icontains=username) + return [UserListSchema.from_orm(user) for user in users] + + +@router.post("/batch") +@super_required +def batch_create(request): + # 批量创建账号 + pass diff --git a/account/migrations/0003_user_raw_password.py b/account/migrations/0003_user_raw_password.py new file mode 100644 index 0000000..33e3642 --- /dev/null +++ b/account/migrations/0003_user_raw_password.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.6 on 2025-03-04 02:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0002_user_role'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='raw_password', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] diff --git a/account/migrations/0004_alter_user_raw_password_alter_user_role.py b/account/migrations/0004_alter_user_raw_password_alter_user_role.py new file mode 100644 index 0000000..3879e7e --- /dev/null +++ b/account/migrations/0004_alter_user_raw_password_alter_user_role.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.6 on 2025-03-04 02:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0003_user_raw_password'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='raw_password', + field=models.CharField(max_length=20, null=True, verbose_name='明文密码'), + ), + migrations.AlterField( + model_name='user', + name='role', + field=models.CharField(choices=[('super', '超级管理员'), ('admin', '管理员'), ('normal', '普通')], default='normal', max_length=20, verbose_name='权限'), + ), + ] diff --git a/account/migrations/0005_alter_user_raw_password.py b/account/migrations/0005_alter_user_raw_password.py new file mode 100644 index 0000000..e709da6 --- /dev/null +++ b/account/migrations/0005_alter_user_raw_password.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.6 on 2025-03-04 02:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0004_alter_user_raw_password_alter_user_role'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='raw_password', + field=models.CharField(blank=True, max_length=20, null=True, verbose_name='明文密码'), + ), + ] diff --git a/account/models.py b/account/models.py index ac204bc..2ab0c6e 100644 --- a/account/models.py +++ b/account/models.py @@ -14,4 +14,16 @@ class User(AbstractUser): max_length=20, choices=RoleChoices.choices, default=RoleChoices.NORMAL, + verbose_name="权限", ) + raw_password = models.CharField( + max_length=20, + null=True, + blank=True, + verbose_name="明文密码", + ) + + def set_password(self, raw_password): + super().set_password(raw_password) + self.raw_password = raw_password + self.save() diff --git a/account/schemas.py b/account/schemas.py index a1e43fe..c334f36 100644 --- a/account/schemas.py +++ b/account/schemas.py @@ -1,11 +1,38 @@ -from ninja import Schema +from ninja import Schema, ModelSchema from pydantic import EmailStr, Field +from .models import User, RoleChoices + + +class UserListSchema(ModelSchema): + @classmethod + def from_orm(cls, obj): + raw_password = obj.raw_password if obj.role == RoleChoices.NORMAL else "" + return cls( + username=obj.username, + raw_password=raw_password, + role=obj.role, + date_joined=obj.date_joined, + last_login=obj.last_login, + is_active=obj.is_active, + ) + + class Meta: + model = User + fields = [ + "username", + "raw_password", + "role", + "date_joined", + "last_login", + "is_active", + ] + class UserRegistrationSchema(Schema): username: str email: EmailStr - password: str = Field(min_length=6) + password: str = Field(min_length=6, max_length=20) class UserLoginSchema(Schema): diff --git a/api/settings.py b/api/settings.py index d99c0f2..25ff8f4 100644 --- a/api/settings.py +++ b/api/settings.py @@ -45,6 +45,7 @@ INSTALLED_APPS = [ "django_extensions", "account", "tutorial", + "challenge", ] MIDDLEWARE = [ @@ -98,9 +99,10 @@ AUTH_PASSWORD_VALIDATORS = [ # { # 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', # }, - # { - # 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - # }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + "OPTIONS": {"min_length": 6}, + }, # { # 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # }, diff --git a/challenge/__init__.py b/challenge/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/challenge/admin.py b/challenge/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/challenge/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/challenge/apps.py b/challenge/apps.py new file mode 100644 index 0000000..ad63d66 --- /dev/null +++ b/challenge/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ChallengeConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'challenge' diff --git a/challenge/migrations/__init__.py b/challenge/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/challenge/models.py b/challenge/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/challenge/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/challenge/views.py b/challenge/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/challenge/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.