2016-06-15 10 views
3

私はDRFを使用しています。ログイン/登録にはDjango-rest-authを使用しています。django-rest-authカスタム登録で余分なフィールドを保存できません

  1. 私は、新しいユーザーを登録している間、私は、ユーザー名と一緒に余分なフィールドを格納するためのカスタム登録シリアライザ、パスワードを持っている余分なフィールド
  2. を持つようにUserモデルをカスタマイズしました。

登録は成功しますが、余分なフィールドはusername、first_name、last_nameおよびpasswordとともに保存されません。

マイモデル:

class UserManager(BaseUserManager): 

    def _create_user(self, username, email, password, is_staff, is_superuser, address, **extra_fields): 
    now = timezone.now() 
    if not username: 
     raise ValueError(_('The given username must be set')) 
    email = self.normalize_email(email) 
    user = self.model(username=username, email=email, 
      is_staff=is_staff, is_active=True, 
      is_superuser=is_superuser, last_login=now, 
      date_joined=now, address=address, **extra_fields) 
    user.set_password(password) 
    user.save(using=self._db) 
    return user 

    def create_user(self, username, email=None, password=None, **extra_fields): 
    return self._create_user(username, email, password, False, False, True, 
       **extra_fields) 

    def create_superuser(self, username, email, password, **extra_fields): 
    user=self._create_user(username, email, password, True, True, 
       **extra_fields) 
    user.is_active=True 
    user.save(using=self._db) 
    return user 


class User(AbstractBaseUser, PermissionsMixin): 
    username = models.CharField(_('username'), max_length=30, unique=True, 
    help_text=_('Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters'), 
    validators=[ 
     validators.RegexValidator(re.compile('^[\[email protected]+-]+$'), _('Enter a valid username.'), _('invalid')) 
    ]) 
    first_name = models.CharField(_('first name'), max_length=30, blank=True, null=True) 
    last_name = models.CharField(_('last name'), max_length=30, blank=True, null=True) 
    email = models.EmailField(_('email address'), max_length=255, 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) 
    receive_newsletter = models.BooleanField(_('receive newsletter'), default=False) 
    birth_date = models.DateField(_('birth date'), auto_now=False, null=True) 
    address = models.CharField(_('address'), max_length=30, blank=True, null=True) 
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") 
    phone_number = models.CharField(_('phone number'), validators=[phone_regex], max_length=30, blank=True, null=True) # validators should be a list 

    USER_TYPES = (
    ('Farmer', 'Farmer'), 
    ('Windmill owner', 'Windmill owner'), 
    ('Solar panel owner', 'Solar panel owner'),) 
    user_type = models.CharField(_('user type'), choices=USER_TYPES, max_length=30, blank=True, null=True) 

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

    objects = UserManager() 

    class Meta: 
    verbose_name = _('user') 
    verbose_name_plural = _('users') 

    def get_full_name(self): 
    full_name = '%s %s' % (self.first_name, self.last_name) 
    return full_name.strip() 

    def get_short_name(self): 
    return self.first_name 

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

マイシリアライザ:

class RegisterSerializer(serializers.Serializer): 
    email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED) 
    first_name = serializers.CharField(required=True, write_only=True) 
    last_name = serializers.CharField(required=True, write_only=True) 
    address = serializers.CharField(required=True, write_only=True) 

    user_type = serializers.ChoiceField(
    choices=(('Farmer', 'Farmer'),('Windmill owner', 'Windmill owner'),('Solar panel owner', 'Solar panel owner'),), 
    style={'base_template': 'radio.html'}, 
    required=True, write_only=True) 


    password1 = serializers.CharField(required=True, write_only=True) 
    password2 = serializers.CharField(required=True, write_only=True) 

    def validate_email(self, email): 
     email = get_adapter().clean_email(email) 
     if allauth_settings.UNIQUE_EMAIL: 
      if email and email_address_exists(email): 
       raise serializers.ValidationError(
        _("A user is already registered with this e-mail address.")) 
     return email 

    def validate_password1(self, password): 
     return get_adapter().clean_password(password) 

    def validate(self, data): 
     if data['password1'] != data['password2']: 
      raise serializers.ValidationError(
       _("The two password fields didn't match.")) 
     return data 

    def get_cleaned_data(self): 
     return { 
      'first_name': self.validated_data.get('first_name', ''), 
      'last_name': self.validated_data.get('last_name', ''), 
      'address': self.validated_data.get('address', ''), 
      'user_type': self.validated_data.get('user_type', ''), 
      'password1': self.validated_data.get('password1', ''), 
      'email': self.validated_data.get('email', ''), 
     } 

    def save(self, request): 
     adapter = get_adapter() 
     user = adapter.new_user(request) 
     self.cleaned_data = self.get_cleaned_data() 
     adapter.save_user(request, user, self) 
     setup_user_email(request, user, []) 
     user.save() 
     return user 

何が悪いのでしょうか?

+0

Django、DRF、rest_authのどのバージョンをお使いですか? – vabada

+0

Django 1.9.7、DRF 3.3.0、django_rest_auth 0.7.0(これは私がここから続いたものです) – Nitish

+0

DRFを3.4.0に更新しました – Nitish

答えて

5

ジャンゴ-allauthはデフォルトでカスタムフィールドを保存することはできませんように思える:

(参照:https://github.com/pennersr/django-allauth/blob/master/allauth/account/adapter.py#L227

その周りに移動するには、単にuser.save()

を行う前に、カスタムフィールド値を割り当てます
self.cleaned_data = self.get_cleaned_data() 
adapter.save_user(request, user, self) 
setup_user_email(request, user, []) 

user.address = self.cleaned_data.get('address') 
user.user_type = self.cleaned_data.get('user_type') 

user.save() 
return user 

これは汚れた修正です。より洗練された方法は、カスタムフィールドをサポートするためにallauthアダプターをオーバーライドすることです。

+0

はいそれは働いた!ありがとう、それはかなりの時間が待っていた! – Nitish

関連する問題