Skip to content
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

How do I toggle between nested and flat values using the same serializer? #182

Open
kdeasymoneysniper opened this issue Jul 11, 2020 · 7 comments

Comments

@kdeasymoneysniper
Copy link

kdeasymoneysniper commented Jul 11, 2020

Hi, this might not be an issue, but just a lack of understanding on my part. I am trying to cut down on the number of serializers that I use, and I came across this package. I want to be able to sort of toggle between nested and flat values for my foreign key fields, and many-to-many fields, depending on the query params at the end of the api call. However, I tried doing that, but it does not seem to work. Here is my code

models.py

`
class SalesProject(models.Model):
sales_project_name = models.CharField(max_length=100)
userProfile = models.ManyToManyField(
'UserProfile', through='ProjectUser', blank=True, related_name="team")

class UserProfile(models.Model):
contact_number = PhoneNumberField(blank=True)
email = models.EmailField(max_length=255)
email_password = models.CharField(max_length=255)
`

serializers.py

`
class UserProfileDynamicSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = 'all'

class SalesProjectDynamicSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
userProfile = UserProfileDynamicSerializer(many=True, read_only=True)
class Meta:
model = SalesProject
fields = 'all'
`

when calling the api without any query

`
"userProfile": [
{
"id": 1,
"contact_number": "-",
"email": "-",
"email_password": "-",
}
],
"sales_project_name": "Ending Scene 222",

`

is it possible for me to return userProfile: [1], when there are no queries? or even when I specify the query as 'userProfile', it still returns me the nested object for userProfile, and I am not sure how to return it as a flat list. Im sorry if I misunderstood anything, thanks for the help. Look forward to your reply, thanks once again!

@yezyilomo
Copy link
Owner

If you want a flat list of ids this is how you should define userProfile field in your SalesProjectDynamicSerializer

userProfile = UserProfileDynamicSerializer(many=True, read_only=True, return_pk=True)

@yezyilomo
Copy link
Owner

Here is the part of documentation about return_pk kwarg https://django-restql.yezyilomo.com/querying_data/#return_pk-kwarg

@kdeasymoneysniper
Copy link
Author

hello, thank you for the prompt reply, but is it possible to dynamically change it based on my query params in the api call? Or would I have to have 2 serializers defined, one being return_pk = True, and the other being without, if I were to want to use both flat lists and nested objects from time to time?

@yezyilomo
Copy link
Owner

Currently it's not possible to do it dynamically, you could have 2 seriealizers or just remove return_pk and add another MethodSerializerField which returns a flat list if ids, I think the latter is easier because you won't need to add another endpoint.

@yezyilomo
Copy link
Owner

You could also return only ids in userProfile field with query={userProfile{id}} but it'll be in form of [{id: 1}, {id: 2}, ...] which is not that bad because you can just extract ids in a list in your frontend.

@kdeasymoneysniper
Copy link
Author

okay thanks, in the event that I am going to use the methodserializerfield, I would have to input the logic of returning the flat list of ids within that method? By the way, can I check for your data manipulation (post or put requests), is there the same functionality of being able to change the fields used based on the query params in the api call? Meaning like, if I were to only specify 'sales_project_name', my put request would only require me to send in a single object of key 'sales_project_name', without sending in 'userProfile' even if it is required in the database table, ONLY in the event that the userProfile has been filled into the database beforehand (through another post or put). Because an issue I am facing with django-rest-framework is that whenever I am updating an object through a POST request, the fields that are 'required' in that model would always be needed to be filled in, regardless of if there are already existing values in the current object in the database. What I would hope for, would be to be able to specify that for a specific PUT request, I am only going to update a single field, and leave the other fields entirely out of my PUT request data, even if they are considered required fields by the database, if there are already existing valid values for those fields in the database already, and I have no intention of changing them with that specific PUT request. Thank you, sorry I am new to DRF, and I tried explaining my situation the best way I could, thank you for taking the time to reply!

@yezyilomo
Copy link
Owner

It looks like you want to do a partial update but you are using PUT which is http method for a full update. If you want to do a partial update use PATCH http method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants