-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using depth
option on serializers should not ignore foreign keys on post/create actions
#7483
Comments
My thoughts about that:
|
alright the workaround that you provided is a nice approach however there is no documentation about it, I agree there should be more explanation about this feature on the documentation, and maybe some example using that work around to be able to provide both functionalities (read/write operations)? |
I would like to suggest that altering the However, it would seem to be the natural expectation for a Many-To-One relationship that we would be able to send the primary key of the foreign object when saving but receive a nested object when reading. This is a very popular request and a work-around solution has been suggested in the following thread... The two-field method was suggested but was decided to be less elegant. You can decide that for yourself. |
Personally, I wouldn't prefer the two field solution, but this solution Btw, I have already created a PR #7415, if it gets merged, we will have a built-in field that takes care of these things |
I am facing the similar scenario, I added Edit: Also, what is the proper way to handling such scenarios, I want to get related information too, but if I don't use the |
The cleanest solution to me was using 2 serializer classes, one for reading info and other for "unsafe" actions. on the view I override the def get_serializer_class(self):
if not self.request.action in SAFE_METHODS:
return LoanSerializer
return LoanInfoSerializer |
I'm really enjoying this solution! Additionally, rather than using For example, let's say I had declared customers and addresses in such a way that a customer can have many addresses but also have one selected as the default. The models might look something like this: # models.py
from django.db import models
class Customer(models.Model):
name = models.CharField(max_length=100, blank=True, default="New Customer")
default_address = models.ForeignKey('Address', related_name='customer_default_address', null=True, blank=True, on_delete= models.SET_NULL)
class Address(models.Model):
content = models.CharField(max_length=100, blank=True, null=True)
customer = models.ForeignKey('Customer', on_delete=models.CASCADE) While The problem with using The answer, I've found, is to use a combination of explicit field declarations using serializers to nest data when desired, and selecting the appropriate serializer depending upon the method, as presented above. Here, I create an additional #serializers.py
from rest_framework import serializers
from .models import Customer, Address
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
class CustomerAddressSerializer(serializers.ModelSerializer):
class Meta:
model = Address
fields = '__all__'
class CustomerInfoSerializer(serializers.ModelSerializer):
default_address = AddressSerializer()
class Meta:
model = Customer
fields = '__all__' Finally, I use the #views.py
from rest_framework import viewsets
from rest_framework.permissions import SAFE_METHODS
from .models import Customer, Address
from .serializers import CustomerSerializer, CustomerInfoSerializer, AddressSerializer
class CustomerView(viewsets.ModelViewSet):
queryset = Customer.objects.all()
filterset_fields = '__all__'
search_fields = ['name']
def get_serializer_class(self):
if not self.request.method in SAFE_METHODS:
return CustomerSerializer
return CustomerInfoSerializer
class AddressView(viewsets.ModelViewSet):
queryset = Address.objects.all()
serializer_class = AddressSerializer
filterset_fields = '__all__'
search_fields = ['content'] This solution allows me to create/update customers by providing the primary key as the value for |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Checklist
master
branch of Django REST framework.Steps to reproduce
depth
option makes you specify the fields for creating or updatingExpected behavior
depth
option should only work on list create options, however it should not ignore those fields when sending Create Update actionsActual behavior
when
depth
option is defined the serializer immediately makes the user define primarykeyrelatedfields for saving/updating stuff otherwise it will ignore them, althought there are workarounds like creating two separate serializer classes (one for safe methods LIST RETRIEVE, and the other one for CREATE UPDATE DELETE), this forces the user to define extra code adding too much verbosity/complexity in it if the project is big enough.Another workaround is to define those fields as primarykeyfields but on the RETRIEVE, LIST methods, they do appear as primarykey too
The text was updated successfully, but these errors were encountered: