chibisov / drf-extensions

DRF-extensions is a collection of custom extensions for Django REST Framework
http://chibisov.github.io/drf-extensions/docs
MIT License
1.47k stars 208 forks source link

Error: invalid literal for int() with base 10: <field> : when lookup field is not the primary key. #105

Closed jrivera294 closed 9 years ago

jrivera294 commented 9 years ago

Hi, I'm having a problem with the drf-ext nested routes. I can change the lookup_field in a viewset without problems, but when I make a nested route with this view as parent, I get this error:

ValueError at /lists/asdf/members/ invalid literal for int() with base 10: 'asdf'

I think that its because the parent_query_lookup is pointing to the primary key of the list model, that is a number, not to the "name" field, that is a string. I can access /list/{name} without problems, but I cant make a nested route to this.

Urls:

list_router = router.register(
    r'lists',
    ListViewSet,
    base_name='list')

member_router = list_router.register(
    r'members',
    MemberViewSet,
    base_name='member',
    parents_query_lookups=['mail_list'])

Viewsets:

class ListViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
    """List resource"""
    model = List
    queryset = List.objects.all()
    serializer_class = ListSerializer
    lookup_field = ('name')

class MemberViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
    """Member resource"""
    lookup_value_regex = '[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}'
    model = Member
    queryset = Member.objects.all()
    serializer_class = MemberSerializer
    lookup_field = ('email')

Models:

class List(models.Model):
    """List model"""
    name = models.CharField(validators=[MinLengthValidator(3)],max_length=27)

class Member(models.Model):
    mail_list = models.ForeignKey(List)
jrivera294 commented 9 years ago

Forget it. I solved it modifying the filter_queryset_by_parents_lookup method.

def filter_queryset_by_parents_lookups(self, queryset):
    parents_query_dict = List.objects.get(name=self.get_parents_query_dict()['mail_list']).id 
    if parents_query_dict:
        try:
            return queryset.filter(id=parents_query_dict)
        except ValueError:
            raise NotFound
    else:
        return queryset
chibisov commented 9 years ago

I believe you've made a bad hack. Just try to change parents_query_lookups=['mail_list'] to parents_query_lookups=['mail_list__name']

list_router = router.register(
    r'lists',
    ListViewSet,
    base_name='list')

member_router = list_router.register(
    r'members',
    MemberViewSet,
    base_name='member',
    parents_query_lookups=['mail_list__name'])  # <= Here
jrivera294 commented 9 years ago

Well... it's embarrassing, When I was testing I typed mail_listname with one ''. And I hought that it will not work.

Thank you very much.