2012-07-19 20 views
6

Tengo dos modelos vinculados por otro modelo a través de una relación de muchos a muchos.Tastypie, filtrado de muchas a muchas relaciones

Aquí están los modelos propios

class Posts(models.Model): 
    id = models.CharField(max_length=108, primary_key=True) 
    tags = models.ManyToManyField('Tags', through='PostTags') 


class Tags(models.Model): 
    id = models.CharField(max_length=108, primary_key=True) 
    posts = models.ManyToManyField('Posts', through='PostTags') 

class PostTags(models.Model): 
    id = models.CharField(max_length=108, primary_key=True) 
    deleted = models.IntegerField() 
    post_id = models.ForeignKey('Posts', db_column='post_field') 
    tag_id = models.ForeignKey('Tags', db_column='tag_field') 

y los recursos tastypie

class PostsResource(ModelResource): 
    tags = fields.ToManyField('django_app.api.TagsResource', 'tags', null=True) 
    class Meta: 
     queryset = Posts.objects.filter(deleted=0) 
     resource_name = 'posts' 

class TagsResource(ModelResource): 
    posts = fields.ToManyField('django_app.api.PostsResource', 'posts', null=True) 
    class Meta: 
     queryset = Tags.objects.filter(deleted=0) 
     resource_name = 'tags' 

Sobre la mesa posttags hay una bandera eliminado, es posible resultados sólo rentabilidad vinculada cuando el indicador de borrado en PostTags es 0?

He probado this atributo de filtro en tastypie pero parece que solo le importa el indicador en la tabla vinculada (es decir, etiquetas o mensajes), no la tabla real que realiza el enlace.

+0

¿Has probado 'queryset = Posts.objects.filter (posttags__deleted = 0)' en el Meta para cada recurso? – astevanovic

+0

Es extraño, eso funciona a medias. Al igual que si imprimo el queryset.query, está haciendo la declaración SQL correcta (como en donde se borró = 0). Pero los resultados devueltos a través de la solicitud de API todavía parecen ignorar la bandera. – Shane

Respuesta

7

Puede filtrar los campos utilizando el atributo lambda bundle mostrando el nombre de la tabla y el nombre del campo.

tags = fields.ToManyField('django_app.api.TagsResource', attribute=lambda bundle: bundle.obj.tags.filter(tags__deleted=0))
1

Wow ... ¡He estado buscando todo el día para esto! el "atributo" es exactamente lo que estaba buscando. Casi empiezo a hackear a mis modelos para filtrar allí por desesperación.

From the Resource Field documentation for ToManyField:

proporciona acceso a datos relacionados a través de una tabla de unión.

Esta subclase requiere que la capa ORM de Django funcione correctamente.

Este campo también tiene un comportamiento especial al tratar con el atributo en que puede tomar un invocable. Por ejemplo, si necesita filtrar la relación inversa , se puede hacer algo como:

subjects = fields.ToManyField(SubjectResource, attribute=lambda bundle: Subject.objects.filter(notes=bundle.obj, name__startswith='Personal')) 
Cuestiones relacionadas