Pregunta ¿Cómo puedo filtrar en un campo en un objeto relacionado?


Si trato de filtrar en un campo en un objeto relacionado, Tastypie devuelve un error. Por ejemplo, ejecutando

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

devuelve "No se permiten búsquedas en más de un nivel de profundidad en el campo de" jugadores ". Esencialmente, estoy tratando de hacer lo que puedo hacer actualmente en el shell de Django:

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

Estoy usando el siguiente código, que simplifiqué por brevedad:

# 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)
    . . . 

Supongo que debido a que UserResource define un filtro en el campo 'nombre de usuario', esto debería funcionar pero no lo hace. Incluso intenté agregar "players__username" al filtro en RoundResource, sin embargo, esto tampoco funcionó.

Yo leo sobre filtrado básico en los documentos y miró el código en GitHub, sin embargo, no parece haber nada para esto. También eché un vistazo a la documentación de filtrado avanzado y no parece encajar en mi caso de uso. He mirado el código Tastypie en GitHub pero no lo entiendo lo suficiente como para saber si 1) estoy haciendo esto mal, o 2) qué anular para que esto funcione.


5
2017-08-10 15:55


origen


Respuestas:


Al parecer, debe incluir específicamente en la lista blanca las búsquedas que abarcan la relación en su filtering línea, así:

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

Al menos yo pensar Ese es el lugar correcto para ponerlo. los documentos relevantes son bastante escasos en los ejemplos. Un boleto de Tastypie, sin embargo, sugiere que esto debería funcionar.


11
2017-08-10 19:04