1

我正在爲django usign django rest框架中的基於令牌的身份驗證編寫API。 我已經使用默認的User模型實現了它。但是我需要在用戶模型中添加更多的細節。 搜索後,我發現AbstractBaseUser,BaseUserMAnager。我已經實現了它,併爲它寫了Serializer,但卻出現錯誤。 網上有太多不同的方法,現在我很困惑哪一種方法是正確的。定製基於令牌的身份驗證的用戶模型django

models.py

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager 

class MyUserManager(BaseUserManager): 
    def create_user(self, email, password): 
     if not email: 
      raise ValueError('Enter email') 

     user = self.model(
      email=email.normalize_email(email) 
     ) 
     user.set_password(password) 
     user.save(using=self._db) 
     return user 

    def create_superuser(self, email, password): 
     user = self.create_user(email, password=password) 
     user.save(using=self._db) 
     return user 


class MyUser(AbstractBaseUser): 

    email = models.EmailField(verbose_name='email address', max_length=255, unique=True, db_index=True) 
    created = models.DateTimeField(auto_now_add=True) 
    is_active = models.BooleanField(default=True) 

    USERNAME_FIELD = 'email' 

    objects = MyUserManager() 

    def get_short_name(self): 
     return self.email 

    def get_full_name(self): 
     return self.email 

    def __unicode__(self): 
     return self.email 

serializers.py

from rest_framework import serializers 
from bsa.models import MyUser 
from django.contrib.auth import get_user_model 


class UserSerializer(serializers.ModelSerializer): 
    password = serializers.CharField(style={'input_type': 'password'}) 

class Meta: 
    model = get_user_model() 
    fields = ['email', 'password'] 

    def create(self, email, password): 
     user = MyUser(email, password) 
     user.set_password(password) 
     user.save() 
     return user 

views.py

from bsa.serializers import UserSerializer 
from rest_framework.decorators import APIView 
from rest_framework.response import Response 

class Test(APIView): 

    def post(self, request): 
     serializer = UserSerializer(data=request.data) 
     if serializer.is_valid(): 
      #getting error here 
      serializer.save() 
      return Response({'detail': "POST Response"}) 
     return Response({'detail': "Response"}) 

個settings.py

""" 
Django settings for BSA2 project. 

Generated by 'django-admin startproject' using Django 1.9.6. 

For more information on this file, see 
https://docs.djangoproject.com/en/1.9/topics/settings/ 

For the full list of settings and their values, see 
https://docs.djangoproject.com/en/1.9/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/1.9/howto/deployment/checklist/ 

# SECURITY WARNING: keep the secret key used in production secret! 
SECRET_KEY = '1$x0gj([email protected]=m!w575!c!n+' 

# SECURITY WARNING: don't run with debug turned on in production! 
DEBUG = True 

ALLOWED_HOSTS = [] 


# Application definition 

AUTH_USER_MODEL = 'bsa.MyUser' 

INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'bsa', 
    'rest_framework', 
] 

MIDDLEWARE_CLASSES = [ 
    'django.middleware.security.SecurityMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
] 

ROOT_URLCONF = 'BSA2.urls' 

TEMPLATES = [ 
    { 
     'BACKEND': 'django.template.backends.django.DjangoTemplates', 
     'DIRS': [os.path.join(BASE_DIR, 'templates')] 
     , 
     '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 = 'BSA2.wsgi.application' 


# Database 
# https://docs.djangoproject.com/en/1.9/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/1.9/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/1.9/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/1.9/howto/static-files/ 

STATIC_URL = '/static/' 

錯誤

Traceback (most recent call last): 
    File "/root/envTut/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view 
    return view_func(*args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/views.py", line 466, in dispatch 
    response = self.handle_exception(exc) 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/views.py", line 463, in dispatch 
    response = handler(request, *args, **kwargs) 
    File "/root/PycharmProjects/BSA2/bsa/views.py", line 20, in post 
    serializer.save() 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 191, in save 
    self.instance = self.create(validated_data) 
TypeError: create() takes exactly 3 arguments (2 given) 

如果我刪除從 'serializers.py' 創建方法 誤差變化自我

Traceback (most recent call last): 
    File "/root/envTut/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view 
    return view_func(*args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/views.py", line 466, in dispatch 
    response = self.handle_exception(exc) 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/views.py", line 463, in dispatch 
    response = handler(request, *args, **kwargs) 
    File "/root/PycharmProjects/BSA2/bsa/views.py", line 20, in post 
    serializer.save() 
    File "/root/envTut/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 191, in save 
    self.instance = self.create(validated_data) 
    File "/root/PycharmProjects/BSA2/bsa/serializers.py", line 16, in create 
    user.save() 
    File "/root/envTut/local/lib/python2.7/site-packages/django/contrib/auth/base_user.py", line 74, in save 
    super(AbstractBaseUser, self).save(*args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/base.py", line 708, in save 
    force_update=force_update, update_fields=update_fields) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/base.py", line 736, in save_base 
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/base.py", line 801, in _save_table 
    forced_update) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/base.py", line 831, in _do_update 
    filtered = base_qs.filter(pk=pk_val) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/query.py", line 790, in filter 
    return self._filter_or_exclude(False, *args, **kwargs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/query.py", line 808, in _filter_or_exclude 
    clone.query.add_q(Q(*args, **kwargs)) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1243, in add_q 
    clause, _ = self._add_q(q_object, self.used_aliases) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1269, in _add_q 
    allow_joins=allow_joins, split_subq=split_subq, 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1203, in build_filter 
    condition = self.build_lookup(lookups, col, value) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1099, in build_lookup 
    return final_lookup(lhs, rhs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 19, in __init__ 
    self.rhs = self.get_prep_lookup() 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 57, in get_prep_lookup 
    return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 744, in get_prep_lookup 
    return self.get_prep_value(value) 
    File "/root/envTut/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 976, in get_prep_value 
    return int(value) 
TypeError: int() argument must be a string or a number, not 'UserSerializer' 

我寫的最的代碼使用django和drf文檔(也有一些博客)。錯誤在serializer.save()

回答

0

我看到的第一個錯誤是def create(self, email, password)應該接收參數selfvalidated_data。例如:

def create(self, validated_data): 
    """Create a new model instance""" 
    return MyUser.objects.create(**validated_data) 

理想情況下,您的序列化程序將包含需要創建此用戶實例的所有字段。

+0

謝謝,它的工作! :) –

相關問題