Django rest framework 字段名称“ia_superuser”对模型“CustomUser”无效
Django rest framework Field name `ia_superuser` is not valid for model `CustomUser`
我在 Django 中编写了自定义用户,剩下的 framework.I 已经编写了自定义用户和自定义序列化程序,我已经在 settings.py 中添加了所有必需品。
当我尝试转到用户应用程序时出现此错误:
在 /api/user/
配置不当
字段名称 ia_superuser
对模型 CustomUser
无效。
请求方法:GET
请求 URL:http://127.0.0.1:8000/api/user/
姜戈版本:3.0.8
异常类型:配置不当
异常值:
字段名称 ia_superuser
对模型 CustomUser
无效。
异常位置:C:\Users\Aireza.virtualenvs\lcodev-lF6rFvWb\lib\site-packages\rest_framework\serializers.py in build_unknown_field, line 1340
Python 可执行文件:C:\Users\Aireza.virtualenvs\lcodev-lF6rFvWb\Scripts\python.exe
Python版本:3.10.2
Python路径:
['F:\Python\lcodev\ecom',
'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\python310.zip',
'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\DLLs',
'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\lib',
'C:\Users\Aireza\AppData\Local\Programs\Python\Python310',
'C:\Users\Aireza\.virtualenvs\lcodev-lF6rFvWb',
'C:\Users\Aireza\.virtualenvs\lcodev-lF6rFvWb\lib\site-packages']
服务器时间:2022 年 3 月 22 日,星期二 11:34:45 +0000
我在项目中有一个api应用程序,用户应用程序在api应用程序中。
有人可以帮忙吗?
谢谢
这就是一切:
用户serializer.py:
from rest_framework import serializers
from .models import CustomUser
from django.contrib.auth.hashers import make_password
from rest_framework.decorators import authentication_classes,permission_classes
class UserSerializer(serializers.HyperlinkedModelSerializer):
def create(self,validated_data):
password = validated_data.pop('password',None) # pop method removes the given index from the list and returns it
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
def update(self,instance , validated_data):
for attr,value in validated_data.item():
if attr == 'password':
instance.set_password(value)
else:
setattr(instance,attr,value)
instance.save()
return instance
class Meta:
model = CustomUser
extra_kwargs = {'password':{'write_only':True}}
fields = ('name' , 'email' , 'phone' ,'password','is_active' , 'is_staff', 'ia_superuser',)
read_only_fields = ('email',)
用户model.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUser(AbstractUser):
name = models.CharField(max_length=50,default='user')
email = models.EmailField(max_length=200 , unique=True)
phone = models.CharField(max_length=20,blank=True,null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
username = None # we dont want the user to be logged in by username
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
session_token = models.CharField(max_length=10,default=0)
用户views.py:
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
from .models import CustomUser
from .serializers import UserSerializer
from django.http import JsonResponse
from django.contrib.auth import get_user_model,login,logout
from django.views.decorators.csrf import csrf_exempt
import random , re
# Create your views here.
def generate_session_token(length = 10):
return ''.join(random.SystemRandom().choice(
[chr(i) for i in range(97,123)] + [str(j) for j in range(10)]
) for k in range(length))
@csrf_exempt
def signin(request):
if not request.method == 'POST':
return JsonResponse({'error': 'Send a post request with valid paramenter only'})
# print(request.POST.get('email', None)) - if you will not get email, None will be printed
username = request.POST['email']
password = request.POST['password']
print(username)
print(password)
# validation part
if not re.match("^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", username):
return JsonResponse({'error': 'Enter a valid email'})
if len(password) < 3:
return JsonResponse({'error': 'Password needs to be at least of 3 char'})
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
if user.check_password(password):
usr_dict = UserModel.objects.filter(
email=username).values().first()
usr_dict.pop('password')
if user.session_token != "0":
user.session_token = "0"
user.save()
return JsonResponse({'error': "Previous session exists!"})
token = generate_session_token()
user.session_token = token
user.save()
login(request, user)
return JsonResponse({'token': token, 'user': usr_dict})
else:
return JsonResponse({'error': 'Invalid password'})
except UserModel.DoesNotExist:
return JsonResponse({'error': 'Invalid Email'})
def signout(request, id):
logout(request)
UserModel = get_user_model()
try:
user = UserModel.objects.get(pk=id)
user.session_token = "0"
user.save()
except UserModel.DoesNotExist:
return JsonResponse({'error': 'Invalid user ID'})
return JsonResponse({'success': 'Logout success'})
class UserViewSet(viewsets.ModelViewSet):
permission_classes_by_action = {'create' : [AllowAny]}
queryset = CustomUser.objects.all().order_by('id')
serializer_class = UserSerializer
def get_permissions(self):
try:
return [permission() for permission in self.permission_classes_by_action[self.action]]
except KeyError:
return [permission() for permission in self.permission_classes]
api 迁移 0001_initial.py:
from django.db import migrations
from api.user.models import CustomUser
class Migration(migrations.Migration):
def seed_data(apps, schema_editor):
user = CustomUser(name="hitesh",
email="hitesh@lco.dev",
is_staff=True,
is_superuser=True,
phone="987654321",
)
user.set_password("12345")
user.save()
dependencies = [
]
operations = [
migrations.RunPython(seed_data),
]
用户urls.py:
from django.urls import path,include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register('',views.UserViewSet)
urlpatterns = [
path('login/',views.signin, name = 'signin'),
path('logout/<int:id>/',views.signout, name = 'signout'),
path('user/',views.UserViewSet),
path('',include(router.urls)),
]
settings.py:
"""
Django settings for ecom project.
Generated by 'django-admin startproject' using Django 3.0.8.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'iqlfys_luymme_hqvp-+!iy@xnk2)(m(k=4!_tl4xpr9gqmofs'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'rest_framework.authtoken',
'api',
'api.category',
'api.product',
'api.user',
'api.order',
'api.payment'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'ecom.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'ecom.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
AUTH_USER_MODEL = "user.CustomUser"
CORS_ORIGIN_ALLOW_ALL = True
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
也许您正在寻找 is_superuser
?
参考:https://docs.djangoproject.com/en/4.0/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser
已编辑:
我认为您只需要这样更新 UserSerializer
class:
class UserSerializer(serializers.HyperlinkedModelSerializer):
def create(self,validated_data):
...
return instance
def update(self,instance , validated_data):
...
return instance
class Meta:
model = CustomUser
extra_kwargs = {'password':{'write_only':True}}
fields = (
'name' ,
'email',
'phone',
'password',
'is_active',
'is_staff',
'is_superuser',)
# note: it's changed from "ia_superuser" to "issuperuser"
read_only_fields = ('email',)
我在 Django 中编写了自定义用户,剩下的 framework.I 已经编写了自定义用户和自定义序列化程序,我已经在 settings.py 中添加了所有必需品。 当我尝试转到用户应用程序时出现此错误:
在 /api/user/
配置不当字段名称 ia_superuser
对模型 CustomUser
无效。
请求方法:GET 请求 URL:http://127.0.0.1:8000/api/user/ 姜戈版本:3.0.8 异常类型:配置不当 异常值:
字段名称 ia_superuser
对模型 CustomUser
无效。
异常位置:C:\Users\Aireza.virtualenvs\lcodev-lF6rFvWb\lib\site-packages\rest_framework\serializers.py in build_unknown_field, line 1340 Python 可执行文件:C:\Users\Aireza.virtualenvs\lcodev-lF6rFvWb\Scripts\python.exe Python版本:3.10.2 Python路径:
['F:\Python\lcodev\ecom', 'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\python310.zip', 'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\DLLs', 'C:\Users\Aireza\AppData\Local\Programs\Python\Python310\lib', 'C:\Users\Aireza\AppData\Local\Programs\Python\Python310', 'C:\Users\Aireza\.virtualenvs\lcodev-lF6rFvWb', 'C:\Users\Aireza\.virtualenvs\lcodev-lF6rFvWb\lib\site-packages']
服务器时间:2022 年 3 月 22 日,星期二 11:34:45 +0000
我在项目中有一个api应用程序,用户应用程序在api应用程序中。
有人可以帮忙吗? 谢谢
这就是一切:
用户serializer.py:
from rest_framework import serializers
from .models import CustomUser
from django.contrib.auth.hashers import make_password
from rest_framework.decorators import authentication_classes,permission_classes
class UserSerializer(serializers.HyperlinkedModelSerializer):
def create(self,validated_data):
password = validated_data.pop('password',None) # pop method removes the given index from the list and returns it
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
def update(self,instance , validated_data):
for attr,value in validated_data.item():
if attr == 'password':
instance.set_password(value)
else:
setattr(instance,attr,value)
instance.save()
return instance
class Meta:
model = CustomUser
extra_kwargs = {'password':{'write_only':True}}
fields = ('name' , 'email' , 'phone' ,'password','is_active' , 'is_staff', 'ia_superuser',)
read_only_fields = ('email',)
用户model.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUser(AbstractUser):
name = models.CharField(max_length=50,default='user')
email = models.EmailField(max_length=200 , unique=True)
phone = models.CharField(max_length=20,blank=True,null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
username = None # we dont want the user to be logged in by username
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
session_token = models.CharField(max_length=10,default=0)
用户views.py:
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
from .models import CustomUser
from .serializers import UserSerializer
from django.http import JsonResponse
from django.contrib.auth import get_user_model,login,logout
from django.views.decorators.csrf import csrf_exempt
import random , re
# Create your views here.
def generate_session_token(length = 10):
return ''.join(random.SystemRandom().choice(
[chr(i) for i in range(97,123)] + [str(j) for j in range(10)]
) for k in range(length))
@csrf_exempt
def signin(request):
if not request.method == 'POST':
return JsonResponse({'error': 'Send a post request with valid paramenter only'})
# print(request.POST.get('email', None)) - if you will not get email, None will be printed
username = request.POST['email']
password = request.POST['password']
print(username)
print(password)
# validation part
if not re.match("^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", username):
return JsonResponse({'error': 'Enter a valid email'})
if len(password) < 3:
return JsonResponse({'error': 'Password needs to be at least of 3 char'})
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
if user.check_password(password):
usr_dict = UserModel.objects.filter(
email=username).values().first()
usr_dict.pop('password')
if user.session_token != "0":
user.session_token = "0"
user.save()
return JsonResponse({'error': "Previous session exists!"})
token = generate_session_token()
user.session_token = token
user.save()
login(request, user)
return JsonResponse({'token': token, 'user': usr_dict})
else:
return JsonResponse({'error': 'Invalid password'})
except UserModel.DoesNotExist:
return JsonResponse({'error': 'Invalid Email'})
def signout(request, id):
logout(request)
UserModel = get_user_model()
try:
user = UserModel.objects.get(pk=id)
user.session_token = "0"
user.save()
except UserModel.DoesNotExist:
return JsonResponse({'error': 'Invalid user ID'})
return JsonResponse({'success': 'Logout success'})
class UserViewSet(viewsets.ModelViewSet):
permission_classes_by_action = {'create' : [AllowAny]}
queryset = CustomUser.objects.all().order_by('id')
serializer_class = UserSerializer
def get_permissions(self):
try:
return [permission() for permission in self.permission_classes_by_action[self.action]]
except KeyError:
return [permission() for permission in self.permission_classes]
api 迁移 0001_initial.py:
from django.db import migrations
from api.user.models import CustomUser
class Migration(migrations.Migration):
def seed_data(apps, schema_editor):
user = CustomUser(name="hitesh",
email="hitesh@lco.dev",
is_staff=True,
is_superuser=True,
phone="987654321",
)
user.set_password("12345")
user.save()
dependencies = [
]
operations = [
migrations.RunPython(seed_data),
]
用户urls.py:
from django.urls import path,include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register('',views.UserViewSet)
urlpatterns = [
path('login/',views.signin, name = 'signin'),
path('logout/<int:id>/',views.signout, name = 'signout'),
path('user/',views.UserViewSet),
path('',include(router.urls)),
]
settings.py:
"""
Django settings for ecom project.
Generated by 'django-admin startproject' using Django 3.0.8.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'iqlfys_luymme_hqvp-+!iy@xnk2)(m(k=4!_tl4xpr9gqmofs'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'rest_framework.authtoken',
'api',
'api.category',
'api.product',
'api.user',
'api.order',
'api.payment'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'ecom.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'ecom.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
AUTH_USER_MODEL = "user.CustomUser"
CORS_ORIGIN_ALLOW_ALL = True
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
也许您正在寻找 is_superuser
?
参考:https://docs.djangoproject.com/en/4.0/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser
已编辑:
我认为您只需要这样更新 UserSerializer
class:
class UserSerializer(serializers.HyperlinkedModelSerializer):
def create(self,validated_data):
...
return instance
def update(self,instance , validated_data):
...
return instance
class Meta:
model = CustomUser
extra_kwargs = {'password':{'write_only':True}}
fields = (
'name' ,
'email',
'phone',
'password',
'is_active',
'is_staff',
'is_superuser',)
# note: it's changed from "ia_superuser" to "issuperuser"
read_only_fields = ('email',)