Как валидировать атрибуты обхода в DRF Serializer?
Итак, стараясь быть как можно более кратким и вписать мою проблему в контекст, я расскажу вам здесь о своих сомнениях. Проблема в том, что я не знаю, как правильно сериализовать данные. Как мне валидировать атрибуты обхода внутри сериализатора?
Моя модель данных структурирована следующим образом, сотрудник принадлежит к единству компании, а это единство принадлежит компании, также есть супер администратор, который может получить доступ к данным всех остальных пользователей.
# models.py
class User(AbstractUser):
class Roles(models.IntegerChoices):
SUPER = 0, _('SuperAdmins')
COMPANY = 1, _('Company')
UNITY = 2, _('Unity')
STAFF = 3, _('Staff')
role: Roles = models.PositiveSmallIntegerField(choices=Roles.choices, default=Roles.STAFF, verbose_name=_("Role"))
objects = UserManager()
class Company(TimeStampedModel):
user: User = models.OneToOneField(User, null=True, on_delete=models.CASCADE, verbose_name=_("User"))
cnpj: str = BRCNPJField(_("CNPJ"), unique=True)
class Unity(TimeStampedModel):
user: User = models.OneToOneField(User, null=True, on_delete=models.CASCADE, verbose_name=_("Usuário"))
postal_code: str = BRPostalCodeField(verbose_name=_("CEP"), unique=False)
company = models.ForeignKey(Company, related_name='units', on_delete=models.CASCADE, verbose_name=_("Compania"))
class Staff(TimeStampedModel):
user: User = models.OneToOneField(User, null=True, on_delete=models.CASCADE, verbose_name=_("User"))
unity = models.ForeignKey(Unity, related_name="staffs", on_delete=models.CASCADE, verbose_name=_("Unity"))
cpf = BRCPFField(_("CPF"))
Мой сериализатор выглядит так:
class RegisterStaffSerializerForModerators(serializers.ModelSerializer):
"""
The main goal of this
"""
username = serializers.CharField(source="user.username", max_length=150, allow_blank=True,
validators=[username_validator], )
email = serializers.EmailField(source="user.email", allow_blank=True, max_length=150)
first_name = serializers.CharField(source="user.first_name", allow_blank=True, max_length=150)
last_name = serializers.CharField(source="user.last_name", allow_blank=True, max_length=150)
password = serializers.CharField(source="user.password", write_only=True, max_length=150)
is_active = serializers.BooleanField(source="user.is_active", read_only=True)
class Meta:
model = Staff
fields = ('id',
'email',
"username",
'first_name',
'last_name',
'password',
'is_active',
"unity",
"cpf"
)
extra_kwargs = {
'is_active': {'read_only': True},
'password': {'write_only': True},
"id": {"read_only": True}
}
# def validate(self, attrs):
# email = attrs.get("email", "")
# print(attrs)
# return super(RegisterStaffSerializerForModerators, self).validate(attrs)
def create(self, validated_data):
user_data = validated_data["user"]
user = User.objects.create_user(
username=user_data.get('username'),
email=user_data.get('email'),
first_name=user_data.get("first_name"),
password=user_data.get('password')
)
staff = Staff.objects.create_staff(user=user, unity=validated_data.get("unity"), cpf=validated_data.get("cpf"))
return staff
Для регистрации нового сотрудника мне нужно проверить поперечные атрибуты, но я не хочу переписывать метод проверки данных и проверять каждое поле, не могу ли я импортировать условия из класса, который я использую в качестве базы? Например: имя пользователя и e-mail должны быть уникальными?
Думаю, вы могли бы использовать UserSerializer
.
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class RegisterStaffSerializerForModerators(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Staff
...