Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering on a related model that contains a generic foreign key leads to an uncaught error. #20

Closed
simone6021 opened this issue Jul 7, 2016 · 2 comments
Labels

Comments

@simone6021
Copy link

Hello,
first let me thank you for sharing this useful code!

What i found is that if you try to filter by a field that point to a related model which has defined a generic foreign key followinf error is returned:
AttributeError at /api/v1/projects/a/ 'GenericForeignKey' object has no attribute 'formfield'

I tried with ForeignKey and ManyToMany on django 1.9.7 and url_filter from github master branch.

You can test it with the following two models:

from django.db import models
from django.contrib.contenttypes.fields import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation


class A(models.Model):
    name = models.CharField(max_length=256, blank=False, null=False)


class B(models.Model):
    name = models.CharField(max_length=256, blank=False, null=False)
    a = models.ForeignKey('A',
                          models.DO_NOTHING,
                          blank=True,
                          null=True,
                          related_name='b_rel')
    content_type = models.ForeignKey(ContentType, models.DO_NOTHING)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

If you try to filter the model 'A' list by the 'b_rel' field the error appears.

Since i actually tried filtering trough djangorestframework 3.3.3 (even if i think that thi issue is generic), i will leave here the relevant code to publish model 'A' to a rest API so you can test it easily.
Just create an 'A' record and paste the following url after you authenticated (trough the django rest framework browsable api or standard django admin):
http://localhost:8000/api/your-app-name/a/?b_rel=1

views.py

from .serializers import *
from projects.models import A, B
from rest_framework.viewsets import ModelViewSet


class ASerializer(serializers.ModelSerializer):
    class Meta:
        model = A
        fields = [
            'name',
            'b_rel',
        ]


class AViewSet(ModelViewSet):
    serializer_class = ASerializer
    queryset = A.objects.all()
    filter_backends = [DjangoFilterBackend]
    filter_fields = [
        'name',
        'b_rel',
    ]

urls.py

from django.conf.urls import include, url
from rest_framework import routers
from projects.views import AViewSet

router = routers.DefaultRouter()

router.register(r'a', AViewSet, 'projects-a')

urlpatterns = [
    url(r'^api/your-app-name/', include(router.urls)),
]

Since the error occurs when filters for the related model ('B') are built automatically, imho the solution is to check wheter a field actually has a formfield or at least exclude the 'GenericForeignKey' field from filters because they do not have a form field by default, see relevant django documentation..

If you prefer a pull request, just tell me.

@miki725 miki725 added the bug label Jul 7, 2016
@miki725
Copy link
Owner

miki725 commented Jan 27, 2017

@simone6021 sorry for late response.

should be fixed in #25 and will be released in 0.3.

thanks for the report

@simone6021
Copy link
Author

Thanks a lot and keep on this good work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants