Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Filtering related fields with related_field#916

SafaAlfulaij started this conversation inGeneral
Discussion options

How can we filter the related fields/authors/1/entries/?

You must be logged in to vote

Replies: 3 comments 3 replies

Comment options

I took some time and now I have a solid thinking that we have to use the related views for related fields.
So, for the above exmaple, it should use a special function ofEntryViewSet instead ofAuthorViewSet'srelated_fields function.
Why?

  1. The actual resource we are fetching here is the related resource. It makes more sense to have it's viewset serve the request.
  2. We get all querysets, filtering, ordering, pagination, permissions for free (almost, after some modifications).
  3. The "parent" resource (author in the example above) is just needed for authentication, and as a reference for related fields.

Currently what I do is this (not optimal and performant, but does the job):

  1. Have the related field viewset handle the relation throughas_view, passing thelist for -to-many andretrieve for single objects.
  2. Pass in the kwargs ofre_path the parent view class, and whatever else needed for filtering.
  3. Inget_queryset, I check if the parent viewset is defined in kwargs, create the viewset, passing proper pk from url arguments, and some other fields, then I doget_object to check permissions, and save the instance for future use if any (could be for making performant queries by select_related the field in the parent request and returning it directly.

This approach has things to consider:

  1. Client must pass the resulting queryset inget_queryset to a parent function to execute filtering for relations.
  2. Performance of creating a viewset for each related fetch can be a lot.
  3. Clients should use another mixin for the relations if the relation resource shouldn't be listed. For example, entryflags shouldn't acceptGET /entry-flags api, but should acceptGET /entry/1/flags.

I'll see if I can clean up the code and have others opinion.

You must be logged in to vote
0 replies
Comment options

related urls served by a single viewset is a simple way of adding relationships links. It has its limitation though such as no filter support. Also important to note is that this got added later. The idea was to simplify the process of providing relationships links.

BeforeRelationshipView was actually used for related urls and can still be used today. So if you wanna use filters better switch toRelationshipView instead of related urls by a single view set. More configuration is needed but gives you the full power of DRF.

With all the complexity and errors related urls served by a single viewset brought I wondered though whether it was a good idea to include this feature. Or maybe there is a better way of simplifying support of related urls then a need to configure each single relationship individuall per resources as currently done withRelationshipView.

You must be logged in to vote
3 replies
@SafaAlfulaij
Comment options

I'm not sure ifRelationshipView can be usednow for normal relations. HTTP actions and the serializer are made for relationships.
I'll dig down and see previous versions of DJA.

Still, I'm convinced in a way that related views should be severed by the respective view.
This way we don't need to repeat filters, select/prefetch related, annotations, pagination, permissions, etc.
Perhaps it can also serve relationships as well, since they are nothing but pointers to the same data, but less detailed.

I believe that#467 will be of a huge benefit here.

@sliverc
Comment options

Sorry I mixed upself andrelated links.Here is an example of a view which was used before the related urls feature got introduced.

@SafaAlfulaij
Comment options

I took a look into those. This is kind of what I do now, with some extra magic.

classBlogViewSet(ModelViewSet):queryset=Blog.objects.all()serializer_class=BlogSerializerdefget_queryset(self,*args,**kwargs):queryset=Blog.objects.all()# simplified# special function to call appropriate function based on kwargs passed to `re_path`,# and to check the permissions and queryset of the "parent" object (Entry for example)returnself.filter_queryset_for_relations(queryset        ).annotate_read_counts()deffilter_queryset_for_Entry(self,queryset,instance):# called within filter_queryset_for_relations, instance is an Entryreturnqueryset.filter(entry_id=instance.id        )deffilter_queryset_for_X(self,queryset,instance):# called within filter_queryset_for_relations, instance is an Xreturnqueryset.filter(# or return another queryset completely (instance.authors.all())x_id=instance.id        )

The current issue is that the schema generation is wrong as it assumes that the entry pk is blog pk (description ofpk param), but it's solvable.

Comment options

I converted this issue to a discussion so it can be further discussed how to move forward or to leave it as it is.

Issue can be extracted once there is an agreement on how to.

You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
General
Labels
None yet
2 participants
@SafaAlfulaij@sliverc
Converted from issue

This discussion was converted from issue #905 on April 16, 2021 20:12.


[8]ページ先頭

©2009-2025 Movatter.jp