Reputation: 4797
Read Only settings doesn't work properly.
No matter if I use read_only_fields
:
read_only_fields = ('id', 'user', 'created_at', 'account_type', 'balance', 'iban')
or read_only
for each serializer field:
class BankAccountSerializer(serializers.ModelSerializer):
id = serializers.StringRelatedField(read_only=True)
user = serializers.StringRelatedField(read_only=True)
created_at = serializers.SerializerMethodField(read_only=True)
account_name = serializers.StringRelatedField(read_only=False)
account_type = serializers.StringRelatedField(read_only=True)
balance = serializers.StringRelatedField(read_only=True)
iban = serializers.StringRelatedField(read_only=True)
class Meta:
model = BankAccount
fields = '__all__'
def get_created_at(self, instance):
return instance.created_at.strftime("%B %d %Y")
This is what my database model looks like:
class BankAccount(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='bankaccounts')
created_at = models.DateTimeField(auto_now_add=True)
account_name = models.CharField(max_length=255)
account_type = models.CharField(max_length=10,
choices=POSITIONS)
balance = models.DecimalField(decimal_places=2, max_digits=12)
iban = models.CharField(max_length=22)
def __str__(self):
return str(self.iban)
My permission classes are the following ones:
permission_classes = [IsUserOrReadOnly, IsAuthenticated]
Whereby the custom IsUserOrReadOnly
class looks like this:
class IsUserOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.user == request.user
My serializer/view looks like this:
class BankAccountViewSet(viewsets.ModelViewSet):
queryset = BankAccount.objects.all()
lookup_field = "iban"
serializer_class = BankAccountSerializer
permission_class = [IsUserOrReadOnly, IsAuthenticated]
What I get from the api endpoint (options method response) is not the result I am expecting, means the field account_name
is still "read_only": true,
as can be seen in the browsable api output:
"actions": {
"PUT": {
"id": {
"type": "field",
"required": false,
"read_only": true,
"label": "Id"
},
"user": {
"type": "field",
"required": false,
"read_only": true,
"label": "User"
},
"created_at": {
"type": "field",
"required": false,
"read_only": true,
"label": "Created at"
},
"account_name": {
"type": "field",
"required": false,
"read_only": true,
"label": "Account name"
},
"account_type": {
"type": "field",
"required": false,
"read_only": true,
"label": "Account type"
},
"balance": {
"type": "field",
"required": false,
"read_only": true,
"label": "Balance"
},
"iban": {
"type": "field",
"required": false,
"read_only": true,
"label": "Iban"
}
}
}
What could here be wrong?
Upvotes: 0
Views: 1780
Reputation: 88689
You don't have to specify all the model fields in your serializer since you are using the ModelSerializer
Try the below serializer,
class BankAccountSerializer(serializers.ModelSerializer):
created_at = serializers.SerializerMethodField()
class Meta:
model = BankAccount
fields = '__all__'
read_only_fields = ('id', 'user', 'created_at', 'account_type', 'balance', 'iban')
def get_created_at(self, instance):
return instance.created_at.strftime("%B %d %Y")
Upvotes: 3
Reputation: 4412
StringRelatedField is read_only.
You can try using SlugRelatedField instead or nested serializers.
Upvotes: 2