Как установить для пользовательского параметра класса менеджера значение required = False - PullRequest
0 голосов
/ 11 марта 2020

Я пишу API для принятия и сохранения информации профиля пользователя. Всего я хочу принять от пользователя 5 параметров, которые указаны ниже.

{
"first_name":"",
"last_name":"",
"email":"",
"password":"",
"profile_picture":""
}

Из этих 5 параметров first_name, last_name, email и password являются обязательными и profile_picture необязательно.

В models.py я упомянул profile_picture как ImageField.

models.py

class Users(AbstractBaseUser, PermissionsMixin):

    """
    This model is used to store user login credential and profile information.
    It's a custome user model but used for Django's default authentication.
    """

    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255, blank=False, null=False)
    last_name = models.CharField(max_length=255, blank=False, null=False)
    profile_picture = models.ImageField(upload_to='profile_picture/', max_length=None, blank=True)
    is_active = models.BooleanField(default=True)

    # defining a custom user manager class for the custom user model.
    objects = managers.UserManager()

    # using email a unique identity for the user and it will also allow user to use email while logging in.
    USERNAME_FIELD = 'email'

В serializers.py я упомянул profile_picture как ImageField с required=False.

serializers.py

class UserSerializer(serializers.Serializer):
    """
    This is a serializer class to validate create user request object.
    """
    class Meta:
        models = 'Users'

    email = serializers.EmailField(allow_blank=False)
    first_name = serializers.CharField(max_length=255, allow_blank=False)
    last_name = serializers.CharField(max_length=255, allow_blank=False)
    profile_picture = serializers.ImageField(max_length=None, allow_empty_file=True, use_url= False, required=False)
    password = serializers.CharField(
        max_length = 255,
        write_only=True,
        allow_blank = False,
        style={
            'input_type' : 'password'
        }
    )

    def create(self, validated_data):

        user_id = models.Users.objects.create_user(**validated_data)

        return user_id

И вот как мой обычай Класс менеджера выглядит следующим образом.

manager.py

class UserManager(BaseUserManager):
    """
    Manager class for the custome user manager. Every model has a default manager class.
    If you define a custome user model then model manager class also needs some customization. 
    """

    def create_user(self, email, first_name, profile_picture, last_name, password=None):
        """
        Here the default create_user() methode of the manager is overridden to achive customization.
        """

        # check email parameter is has some value ir its empty.
        if not email:

            # raise the value error if it is empty.
            raise ValueError('Users must have an email address.')

        # defining a model instance by mapping parameters with the model fields.
        user = self.model(
            # normalizing email i.e converting it to lower case.
            email = self.normalize_email(email),
            first_name = first_name,
            last_name = last_name,
            profile_picture = profile_picture,
            )
        # encrypting user password using default method set_password() 
        user.set_password(password)

        # saving instance in to model.
        user.save(using=self._db)

        # return model instance.
        return user

Когда я передаю объект без profile_picture, он возвращает мне указанную ниже ошибку.

TypeError at /user/create/
create_user() missing 1 required positional argument: 'profile_picture'

Поэтому я попытался еще раз после удаления параметра profile_picture из create_user() метода класса менеджера. Но тогда API не работает для пользователей, которые хотят загрузить свои profile_picture.

Ответы [ 3 ]

1 голос
/ 11 марта 2020

Перво-наперво: вам нужно оставить значение null = True для поля изображения, так как пусто для проверки внешнего интерфейса, а null для проверки внутреннего интерфейса.

profile_picture = models.ImageField(upload_to='profile_picture/', max_length=None, blank=True, null=True)

Во-вторых, установите profile_picture в качестве аргумента ключевого слова, если хотите сделать его необязательным.

def create_user(self, email, first_name, last_name, password=None,profile_picture=None):
1 голос
/ 11 марта 2020

Чтобы установить какое-либо поле не обязательным, вы должны добавить null=True и blank=True к нему, поэтому попробуйте добавить null=True в ваших models.py:

profile_picture = models.ImageField(..., null=True)
0 голосов
/ 11 марта 2020

Вы можете установить значение по умолчанию для фотографии профиля, пока пользователь не изменит его

profile_picture = models.ImageField(..., null=True, default="path/to/default/image.jpeg")
...