Django rest framework запись / обновление вложенного сериализатора
Как написать и обновить вложенный сериализатор в drf. У меня есть две модели. Просто пример ниже.
Class Account (AbstractBaseUser):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(max_length=100, unique=True
Class USerProfile(models.Model):
user = models.ForeignKey(Account, on_delete=models.CASCADE)
address_line_1 = models.CharField(max_length=100)
address_line_2 = models.CharField(max_length=100)
phone = models.IntegerField(null=True)
уже есть AccountSerilaizer
для вида Регистрация
class AccountSerializer(ModelSerializer):
confirm_password = CharField(write_only=True)
class Meta:
model = Account
fields = ["first_name", "last_name", "email", "password", "confirm_password"]
extra_kwargs = {
"password": {"write_only": True},
}
def validate_email(self, value):
qs = Account.objects.filter(email__iexact=value)
if qs.exists():
raise ValidationError("Email already exists")
return value
def validate(self, attrs):
if attrs.get("first_name") == "" or attrs.get("last_name") == "":
raise ValidationError("Names cannot be blank")
return attrs
def validate_password(self, data):
if len(data) < 8:
raise ValidationError(
"Password should be atleast 8 digits or characters or letters"
)
return data
def validate(self, data):
if data["password"] != data.pop("confirm_password"):
raise ValidationError({"error": "Passwords donot match"})
return data
def create(self, validated_data):
user = Account.objects.create_user(**validated_data)
return user
def update(self, instance, validated_data):
instance.first_name = validated_data.get("first_name", instance.first_name)
instance.last_name = validated_data.get("last_name", instance.last_name)
instance.email = validated_data.get("email", instance.email)
instance.save()
return instance
Итак UserProfile
это FK к Account
, как обновить/записать UserProfile
и как получить request.user
внутри сериализатора во время метода create/update
и я использую JWT аутентификацию. Есть сторонний пакет, с которым я познакомился, чтобы написать вложенный сериализатор, но я хочу знать, как обойтись без него.
Всякий раз, когда вы имеете дело с полем пользователя, где вам нужно получить вошедшего пользователя, вы можете использовать CurrentUserDefault
на сериализаторе. Еще одна вещь, пользователь в методе create не получает пользователя из данных сериализатора AccountSerializer. он получает его из request.
Если вы хотите создать и подтвердить пользователя, используя профиль пользователя, то сделайте следующее
class UserprofileSerializer(ModelSerializer):
user = AccountSerializer(required=True)
class Meta:
model = UserProfile
fields = [
"user",
"address_line_1",
"address_line_2",
"city",
"state",
"country",
"gender",
"phone",
"date_of_birth",
]
def create(self, validated_data):
user_data = validated_data.pop('user')
user_serializer = AccountSerializer("user")
user_serilializer.is_valid(raise_exception = True)
user = user_serilizer.save()
user_profile =UserProfile.objects.create(user=user, **validated_data)
return user_profile
иначе
class UserprofileSerializer(...):
user = serializers.PrimaryKeyRelatedField(
default=serializers.CurrentUserDefault()
)
документация по CurrentUserDefault
находится здесь.