修改用户管理
This commit is contained in:
@@ -1,4 +1,13 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
from .models import User
|
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)
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
from typing import List, Optional
|
||||||
from django.contrib.auth import authenticate, login, logout
|
from django.contrib.auth import authenticate, login, logout
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from ninja import Router
|
from ninja import Router
|
||||||
from ninja.errors import HttpError
|
from ninja.errors import HttpError
|
||||||
from .schemas import UserRegistrationSchema, UserLoginSchema
|
from .schemas import UserListSchema, UserRegistrationSchema, UserLoginSchema
|
||||||
from .models import RoleChoices, User
|
from .models import RoleChoices, User
|
||||||
|
from .decorators import super_required
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
@@ -38,8 +40,23 @@ def user_logout(request):
|
|||||||
|
|
||||||
@router.get("/profile")
|
@router.get("/profile")
|
||||||
def my_profile(request):
|
def my_profile(request):
|
||||||
# 暂时这样写
|
# 首页获取用户状态
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
return {"username": request.user.get_username(), "role": request.user.role}
|
return {"username": request.user.get_username(), "role": request.user.role}
|
||||||
else:
|
else:
|
||||||
return {"username": "", "role": RoleChoices.NORMAL}
|
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
|
||||||
|
|||||||
18
account/migrations/0003_user_raw_password.py
Normal file
18
account/migrations/0003_user_raw_password.py
Normal file
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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='权限'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
account/migrations/0005_alter_user_raw_password.py
Normal file
18
account/migrations/0005_alter_user_raw_password.py
Normal file
@@ -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='明文密码'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -14,4 +14,16 @@ class User(AbstractUser):
|
|||||||
max_length=20,
|
max_length=20,
|
||||||
choices=RoleChoices.choices,
|
choices=RoleChoices.choices,
|
||||||
default=RoleChoices.NORMAL,
|
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()
|
||||||
|
|||||||
@@ -1,11 +1,38 @@
|
|||||||
from ninja import Schema
|
from ninja import Schema, ModelSchema
|
||||||
from pydantic import EmailStr, Field
|
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):
|
class UserRegistrationSchema(Schema):
|
||||||
username: str
|
username: str
|
||||||
email: EmailStr
|
email: EmailStr
|
||||||
password: str = Field(min_length=6)
|
password: str = Field(min_length=6, max_length=20)
|
||||||
|
|
||||||
|
|
||||||
class UserLoginSchema(Schema):
|
class UserLoginSchema(Schema):
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ INSTALLED_APPS = [
|
|||||||
"django_extensions",
|
"django_extensions",
|
||||||
"account",
|
"account",
|
||||||
"tutorial",
|
"tutorial",
|
||||||
|
"challenge",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -98,9 +99,10 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
# {
|
# {
|
||||||
# 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
# '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',
|
# 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
# },
|
# },
|
||||||
|
|||||||
0
challenge/__init__.py
Normal file
0
challenge/__init__.py
Normal file
3
challenge/admin.py
Normal file
3
challenge/admin.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
6
challenge/apps.py
Normal file
6
challenge/apps.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ChallengeConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'challenge'
|
||||||
0
challenge/migrations/__init__.py
Normal file
0
challenge/migrations/__init__.py
Normal file
3
challenge/models.py
Normal file
3
challenge/models.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
3
challenge/views.py
Normal file
3
challenge/views.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
Reference in New Issue
Block a user