How do I filter on a field in a related object?

偶尔善良 提交于 2019-12-05 00:18:09

问题


If I try to filter on a field in a related object then Tastypie returns an error. For example, running

curl -H "Accept: application/json" \
     "http://localhost:8080/wordgame/api/v1/rounds/?format=json&players__username=moe"

returns "Lookups are not allowed more than one level deep on the 'players' field." Essentially, I am trying to do what I can currently do in the Django shell:

Round.objects.all().filter(players__username=moe.username)

I am using the following code, which I simplified for brevity:

# wordgame/api.py which has tastypie resources
class RoundResource(ModelResource):
    players = fields.ManyToManyField(UserResource, 'players',full=True)
    . . .

    class Meta:
        queryset = Round.objects.all()
        resource_name = 'rounds'
        filtering = {
            'players': ALL,
        }

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'players'
        filtering = {
            'username': ALL,
        }

# wordgame/models.py which has Django models
class Round(models.Model):
    players = models.ManyToManyField(User)
    word = models.CharField(max_length=75)
    . . . 

I'm assuming that because UserResource defines a filter on the field 'username' that this should work but it does not. I even attempted to add "players__username" to the filter in RoundResource, however this did not work either.

I read about basic filtering in the docs and looked at the code on GitHub however there doesn't seem to be anything for this. I also took a look at the advanced filtering documentation and it doesn't seem to fit my use case. I've looked at the Tastypie code on GitHub but don't understand it enough to figure out if 1) I am doing this wrong, or 2) what to override to get this to work.


回答1:


Apparently, you need to specifically white-list the relation-spanning lookups in your filtering line, like this:

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'players'
        filtering = {
            'username': ALL_WITH_RELATIONS,
        }

At least, I think that's the right place to put it. The relevant docs are fairly slim on examples. A Tastypie ticket, though, suggests this should work.



来源:https://stackoverflow.com/questions/11905206/how-do-i-filter-on-a-field-in-a-related-object

工具导航Map