Хранение дополнительной информации в django с помощью absrtactuser - PullRequest
0 голосов
/ 23 мая 2018

Я создал пользовательский класс пользователя в django (AbstarctUser).Все работает нормально, но мой пароль хранится в виде обычного текста в базе данных даже после регистрации в admin.py.У меня нет никаких явно определенных форм.

Также я использую вложенные сериализаторы, следующие учебник .

Мой код такой, как показано ниже

from django.contrib import admin
from .models import BasicUserInfo
from django.contrib.auth.admin import UserAdmin


class BasicUserAdmin(UserAdmin):
    pass

admin.site.register(BasicUserInfo, BasicUserAdmin)

Отредактировано для добавления моделей и представлений

Models.py

class BasicUserInfo(AbstractUser):
    email = models.EmailField(primary_key=True, unique=True, db_index=True)

class UserInfo(models.Model):
    user = models.ForeignKey(BasicUserInfo, on_delete=models.CASCADE)

Views.py

serializer = AddUserSerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
    serializer.create(validated_data=request.data)

Serializers.py

class BasicUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = BasicUserInfo
        fields = ('username', 'password', 'email')

    print("hete")

    def create(self, validated_data):
        retval =  BasicUserInfo.objects.create(**validated_data)
        password = validated_data.pop('password')
        self.password = make_password(password)
       # self._password = password
        return retval

class AddUserSerializer(serializers.ModelSerializer):
    user = BasicUserSerializer(required=True)

    class Meta:
        model = UserInfo
        fields = ('phoneNo')

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = BasicUserSerializer.create(BasicUserSerializer(), validated_data=user_data)
        user_info, created = UserInfo.objects.update_or_create(user=user, phoneNo=validated_data.pop('phoneNo'))
        return user_info

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Хитрость заключается в том, чтобы использовать user.set_password(password) -> это внутренне запускает механизм хэширования пароля: Вот код Django, который делает это:

def set_password(self, raw_password):
    self.password = make_password(raw_password)
    self._password = raw_password

def make_password(password, salt=None, hasher='default'):
    """
    Turn a plain-text password into a hash for database storage

    Same as encode() but generate a new random salt. If password is None then
    return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string,
    which disallows logins. Additional random string reduces chances of gaining
    access to staff or superuser accounts. See ticket #20079 for more info.
    """
    if password is None:
        return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
    hasher = get_hasher(hasher)
    salt = salt or hasher.salt()
    return hasher.encode(password, salt)

Таким образом, проблема в serializers.create(**validated_data) не выполняется make_password операция.Приведенный выше ответ прекрасно работает, за исключением того, что он выполняет две вещи по-разному - он спасает пользователя дважды (один раз в serailizer.create и снова во время `user.save ()) - он не меняет все в сериализаторе, часть работыразделение на ч / б сериализатор и представление.

Если вы хотите сохранить все это внутри сериализатора, вы можете сделать следующее:

class AddUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = BasicUserInfo

    def validate_password(self, value):
        return make_password(value)

Обновление:

Я сделал кучу правок;и попытался объяснить почему.Пожалуйста, читайте терпеливо и вносите изменения по своему усмотрению.

class BasicUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = BasicUserInfo
        fields = ('username', 'password', 'email')

    def validate_password(self, value):
        return make_password(value)

class AddUserSerializer(serializers.ModelSerializer): 
    user = BasicUserSerializer(required=True) 
    class Meta: 
        model = UserInfo 
        fields = ('phoneNo') 

    def create(self, validated_data): 
        user_data = validated_data.pop('user') 
        user_serializer = BasicUserSerializer(data=user_data)
        if user_serializer.is_valid(raise_exception=True):
            user = user_serializer.save()
        validated_data['user'] = user
        return UserInfo.objects.create(**validated_data)
0 голосов
/ 23 мая 2018

Не следует использовать так:

serializer = AddUserSerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
    serializer.create(validated_data=request.data)

, если пароль в проверенных данных

, лучше использовать так:

password = request.data.pop('password', '')
if not password:
    raise ValidationError('password must not be empty')
serializer = AddUserSerializer(data=request.data)
serializer.is_valid(raise_exception=ValueError):
user = serializer.create(validated_data=request.data)
user.set_password(password)
user.save()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...