Django REST框架:管理器不可用;用户已被换成'api.User'

时间:2014-11-06 01:04:33

标签: python django model

我遇到了Django用户和Django REST框架的问题。

在我的设置中,我定义了一个自定义用户模型:

AUTH_USER_MODEL = 'api.User'

在我的sandbox.api包中,我在models.py文件中定义了这个模型:

from django.db import models
from django.core.exceptions import ValidationError
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import UserManager
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
from django.core import validators
from django.core.mail import send_mail
from django.utils import timezone
from django.core.exceptions import NON_FIELD_ERRORS
from random import randrange

class User(AbstractBaseUser, PermissionsMixin):
    """
    Custom user class
    """
    username = models.CharField(_('username'), max_length=20, unique=True,
        help_text=_('Required. 30 characters or fewer. Letters and digits only.'),
        validators=[
            validators.RegexValidator(r'^[a-z0-9A-Z]{1,20}$', _('Enter a valid username.'), 'invalid')
        ])
    email = models.EmailField(_('email address'), max_length=60, blank=False, null=False, unique=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

    def clean(self):
        errors = {}
        id = self.id
        if not id:
            id = 0
        n = len(list(User.objects.raw('SELECT id FROM auth_user WHERE LOWER(username) = LOWER(%s) AND id != %s', [self.username, id])))
        if n > 0:
            errors['username'] = 'User with this username already exists.'
        n = len(list(User.objects.raw('SELECT id FROM auth_user WHERE LOWER(email) = LOWER(%s) AND id != %s', [self.email, id])))
        if n > 0:
            errors['email'] = 'User with this e-mail address already exists.'
        if len(errors) > 0:
            raise ValidationError(errors)

    def save(self, *args, **kwargs):
        self.username = self.username.lower()
        self.email = self.email.lower()
        super(User, self).save(*args, **kwargs)

    def __unicode__(self):
        return u'%s' % self.username

    class Meta:
        db_table = 'auth_user'
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = False

在我的sandbox.api包中,我在serializers.py文件中定义了一个序列化程序:

class UserSerializer(ExtSerializer):
    """
    User serializer
    """
    name = serializers.SerializerMethodField('get_name')
    description = serializers.SerializerMethodField('get_description')
    url = serializers.SerializerMethodField('get_url')
    location = serializers.SerializerMethodField('get_location')
    facebook_id = serializers.SerializerMethodField('get_facebook_id')
    twitter_id = serializers.SerializerMethodField('get_twitter_id')
    path = serializers.SerializerMethodField('get_path')
    feed = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-feed-collection')
    timeline = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-timeline-collection')
    followers = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-follower-collection')
    following = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-following-collection')
    posts_count = serializers.SerializerMethodField('get_posts_count')
    followers_count = serializers.SerializerMethodField('get_followers_count')
    following_count = serializers.SerializerMethodField('get_following_count')

    def get_path(self, user):
        request = self.context['view'].request
        return reverse_lazy('user-singleton', kwargs={
            "username": user.username
        }, request=request, format=FORMAT_SUFFIX)

    def get_facebook_id(self, user):
        return user.profile.facebook_id

    def get_twitter_id(self, user):
        return user.profile.twitter_id

    def get_posts_count(self, user):
        return Post.objects.filter(author__pk=user.pk).count()

    def get_following_count(self, user):
        return Follower.objects.filter(follower=user.pk).count()

    def get_followers_count(self, user):
        return Follower.objects.filter(following=user.pk).count()

    def get_name(self, user):
        return user.profile.name

    def get_description(self, user):
        return user.profile.description

    def get_url(self, user):
        return user.profile.url

    def get_location(self, user):
        return user.profile.location

    class Meta:
        model = User
        fields = ('path', 'id', 'username', 'name', 'description', 'url', 'location', 'is_active',
            'facebook_id', 'twitter_id', 'email',
            'feed', 'timeline', 'following', 'followers',
            'posts_count', 'following_count', 'followers_count')

我100%认为网址绑定对API是正确的。当我尝试获取用户列表时,我得到以下错误:

Manager isn't available; User has been swapped for 'api.User'

有没有人知道这里发生了什么?我在Python 2.7.6上使用Django 1.7.1。

提前感谢您的帮助!

亲切的问候, ķ。

1 个答案:

答案 0 :(得分:4)

  

您应该引用该用户,而不是直接引用User   使用django.contrib.auth.get_user_model()的模型。这种方法会   返回当前活动的用户模型 - 自定义用户模型(如果有)   指定,或用户否则。

有点迟到但仍然......