DRF - Относить объект к другому объекту с помощью представлений, сериализаторов и внешних ключей
В принципе, у меня есть две модели с отношениями один-к-одному. И я хочу получить информацию из одной, когда я вызываю другую.
Мои модели:
class Customer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class CurrentAccount(models.Model):
customer_account = models.ForeignKey(Customer, on_delete=models.CASCADE,
related_name='customer_account', blank=True, null=True)
balance = models.FloatField()
Так что я могу просто вызвать POST и создать клиента, у этого клиента будет id, first_name и last_name. На данный момент все работает.
Но когда я пытаюсь вызвать свою конечную точку для создания CurrentAccount, информируя моего клиента о том, что нужно перейти, ничего не происходит.
Мой вход:
{
"customer_account": 1 #this is some id from an Customer that is already created,
"balance": 0.0
}
Вывод, который я ожидал:
{
"id": 42,
"customer_account": {
"id": 2,
"first_name": "Michele",
"last_name": "Obama"
}
"balance": 0.0
}
Вывод, который я получил:
{
"id": 4,
"balance": 0.0
}
Как видите, Django игнорирует отношения (В базе данных поле 'customer_account_id' тоже null, так что это не просто проблема с моим возвратом).
Вот мои сериализаторы:
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ('id', 'first_name', 'last_name')
class CurrentAccountSerializer(serializers.ModelSerializer):
customer_account = CustomerSerializer(read_only=True)
class Meta:
model = CurrentAccount
fields = ('id', 'customer_account', 'balance')
И мои представления для создания CurrentAccount:
@api_view(['GET', 'POST'])
def currentaccount_list_view(request):
if request.method == 'GET':
try:
data = CurrentAccount.objects.all()
ser = CurrentAccountSerializer(data, many=True)
return response_success(data=ser.data)
except Exception as e:
return response_failed(e.args)
elif request.method == 'POST':
try:
ser = CurrentAccountSerializer(data=request.data, context={'request': request})
if ser.is_valid():
ser.save()
return response_success(data=ser.data)
else:
return response_failed('Something wrong with the input data')
except Exception as e:
return response_failed(e.args)
Так что я в основном хочу понять, как отношения работают на Django и как работать с контекстом DRF, используя сериализаторы. Я уже просмотрел документацию, но я все еще не понимаю.
Проблема заключается в том, что в сериализаторе CurrentAccountSerializer
вы устанавливаете поле customer_account
как доступное только для чтения. Вы также должны использовать два сериализатора с CurrentAccount
, первый для перечисления существующих экземпляров, а второй для создания новых.
сериализаторы
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ('id', 'first_name', 'last_name')
class CurrentAccountInfoSerializer(serializers.ModelSerializer):
customer_account = CustomerSerializer(read_only=True)
class Meta:
model = CurrentAccount
fields = ('id', 'customer_account', 'balance')
class CurrentAccountCreationSerializer(serializers.ModelSerializer):
customer_account = serializers.PrimaryKeyRelatedField(queryset=Customer.objests.all())
class Meta:
model = CurrentAccount
fields = ('id', 'customer_account', 'balance')
def create(self, validated_data):
return CurrentAccount.objects.create(**validated_data)
просмотров
@api_view(['GET', 'POST'])
def currentaccount_list_view(request):
if request.method == 'GET':
try:
data = CurrentAccount.objects.all()
ser = CurrentAccountInfoSerializer(data, many=True)
return response_success(data=ser.data)
except Exception as e:
return response_failed(e.args)
elif request.method == 'POST':
try:
ser = CurrentAccountCreationSerializer(data=request.data, context={'request': request})
if ser.is_valid():
instance = ser.save()
return response_success(data=CurrentAccountInfoSerializer(instance=instance).data)
else:
return response_failed('Something wrong with the input data')
except Exception as e:
return response_failed(e.args)