Add support for source with attributes in extra_kwargs of ModelSerializer - #9077
Add support for source with attributes in extra_kwargs of ModelSerializer#9077BergLucas wants to merge 22 commits into
Conversation
|
___________________________________ summary ____________________________________ |
auvipy
left a comment
There was a problem hiding this comment.
And this should also require documentation update as far as I can understand!
b10dfc2 to
c1ccc37
Compare
auvipy
left a comment
There was a problem hiding this comment.
does this change conform with the principle of adding compatibility with django? I'm not fully convinced about the merit of the new change
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
|
I think this is still relevant and shouldn't be marked as stale. |
| if attr not in attr_info.relations: | ||
| break |
There was a problem hiding this comment.
This seems to cause trailing attributes to be ignored if they are "after" other relation attributes, but are not a relation themselves. Is this intended?
If so, I think this scenario should also have a test case.
There was a problem hiding this comment.
It is not really intended. Is it possible to have attributes other than relations with sufficient information in this function to be able to follow them? As far as I know, this isn't the case, so I just did it this way. It's also possible that I misunderstood your comment
|
@auvipy Do you know why the bot doesn't remove stale label when there is a new comment? |
|
@BergLucas Hey 👋🏻 Is it possible for you to rebase this branch from the latest main, so it won't be closed as stale and we can push for another tour of review & testing? Thanks in advance. |
…://github.com/BergLucas/django-rest-framework into improvement/source-attributes-in-extra_kwargs
|
Hi @ulgens , Thanks for your reviews! I've rebased the branch and responded to the comments. (Sorry for the delay, I've been quite busy these last few weeks.) |
There was a problem hiding this comment.
Pull request overview
Adds support for using dotted source paths (e.g. user.username) in ModelSerializer.Meta.extra_kwargs so that DRF can infer the correct serializer field type/validators from related model fields, without requiring explicit field declarations.
Changes:
- Update
ModelSerializer.get_fields()to resolve dottedsourcepaths across model relations when building fields. - Add a regression test asserting the generated field representation includes validators from related model fields (e.g.
User.username). - Document the new
extra_kwargscapability with an example mapping serializer fields to related model attributes.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
rest_framework/serializers.py |
Adds dotted-source traversal to choose the correct related model metadata when building auto-generated fields. |
tests/test_model_serializer.py |
Adds coverage for dotted source paths in extra_kwargs and expected field mapping/validators. |
docs/api-guide/serializers.md |
Documents using extra_kwargs with source to map serializer fields to related model fields. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Critical test defects and unsupported to-many traversal must be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
rest_framework/serializers.py:1174
- A dotted target field can bring in a
UniqueValidatorwhose queryset belongs to the related model, but that validator receives the root serializer instance. On an update it therefore excludesUser(pk=profile.pk)rather thanprofile.user; an unchanged value may be rejected when those PKs differ, and a real conflict may be skipped when they coincide with another user's PK. Contextual validators need to resolve the related instance (or be omitted for dotted fields).
field_class, field_kwargs = self.build_field(
source, source_info, source_model, depth
)
rest_framework/serializers.py:1165
- Treating a related model's URL field as traversable produces the wrong field:
build_url_field()returnsHyperlinkedIdentityField, whose constructor forcibly resetssource='*'. Thussource='user.url'serializes the root object with the user's view name instead of traversing touser. Remove this special case unless nested identity URLs are implemented explicitly.
or attr == self.url_field_name
- Files reviewed: 3/3 changed files
- Comments generated: 5
- Review effort level: Balanced
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
auvipy
left a comment
There was a problem hiding this comment.
push some changes. please cross check again
There was a problem hiding this comment.
🟡 Changes recommended
A critical indentation error prevents imports, and dotted fields mishandle uniqueness validation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
tests/test_model_serializer.py:881
- The PR explicitly preserves the full dotted path in configuration errors, but this assertion only checks the exception type, so an error mentioning only
namewould still pass. Assert the dotted source in the message to protect that behavior.
with self.assertRaises(ImproperlyConfigured):
InvalidUserProfileSerializer().fields
tests/test_model_serializer.py:881
- Add two blank lines before the next top-level class. The current adjacency violates E305, which is enabled by the repository's flake8 configuration (
pyproject.toml:101-104); surrounding top-level classes in this file also consistently use two blank lines.
InvalidUserProfileSerializer().fields
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Balanced
| field_class, field_kwargs = self.build_field( | ||
| source, info, model, depth | ||
| source, source_info, source_model, depth | ||
| ) |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
refs #4688
Description
Hello dear maintainers, it's my first contribution to django rest framework so I hope I didn't do anything wrong.
In the pull request referenced above, there is someone that mentioned that we could not use source with attributes in extra_kwargs of a ModelSerializer.
For example, the following code would create an error:
I think it could be a very interesting feature because at the moment, when we have a foreign key to another model, we're obliged to specify the fields explicitly in the serializer. However, this means that if we have special validators on the fields of our model, we're obliged to put them back on the serializer fields.
For example, the
usernamefield of Django's defaultUserhas a special validator so if we just define a basicCharField, it would not validate the data the same way as the model would validate it:This could create a difference between the way the model validates data and the way the serializer validates data if we forgot a validator or if we change the model without changing the serializer.
In this pull request, I added this feature so that we could just specify the model field we want in the source of extra_kwargs and it will generate the right field on the serializer.
The code may seem a little odd, but I've tried to keep the changes in one place only. I've also tried to maintain a good error message so that, if at any point the path to the field is wrong, it returns the full path in the error message and not just part of it.
Thanks for reading and please let me know if there are any changes that could be made.