Basically I have two models with one-to-one relationship. And I want retrieve information from one, when I call the other.
My models:
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()
So I can just call an POST and create an Customer, that customer will have id, first_name and last_name. For now everything is working.
But when I try to call my endpoint to create an CurrentAccount informing my Customer to relate, nothing happens.
My input:
{
"customer_account": 1 #this is some id from an Customer that is already created,
"balance": 0.0
}
The output that I expected:
{
"id": 42,
"customer_account": {
"id": 2,
"first_name": "Michele",
"last_name": "Obama"
}
"balance": 0.0
}
The output that I received:
{
"id": 4,
"balance": 0.0
}
As you can see, Django are ignoring the relationship (In the database the field 'customer_account_id' is null too, so isn't just an problem with my return).
Here is my serializers:
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')
And my views to create the 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)
So I basically want to understand how the relationships works on Django and how to handle with DRF context, using serializers. I already looked the docs, but I still not understanding.
CodePudding user response:
The problem is with the CurrentAccountSerializer
serializer, you set the customer_account
field as read only. You should also use two serializers with CurrentAccount
, the first to list existing instances and the second to create new ones.
serializers
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)
views
@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)