Search code examples
pythondjangomodeltastypie

Tastypie using custom detail_uri_name, mismatched type error


I am trying to override get_bundle_detail_data

class MyResourse(ModelResource):
     foo = fields.CharField( attribute = 'modelA__variableOnModelA' )
     def get_bundle_detail_data(self, bundle):
         return bundle.obj.foo
     class Meta:
         resource_name='resource'

With the line of code foo = fields.CharField( attribute = 'modelA__variableOnModelA' ), I am setting the variable foo on the resource MyResource, to a variable on modelA called variableOnModelA. This works nicly.

But I am trying to make variableOnModelA be the identifier for MyResource, that way I can do /api/v1/resource/bar/ to get the detailed MyResource with the variable foo set to bar.

The problem I am having is the error: Invalid resource lookup data provided (mismatched type). What is this error saying?

Ultimate Question: How can I use foo as the detail_uri_name?

EDIT Model:

class AgoraUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='agora_user')
    class Meta:
        db_table = 'agora_users'

Urls:

full_api = Api(api_name='full')
full_api.register(AgoraUserResourse())
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include(full_api.urls)),
    url(r'^', include(min_api.urls)),
    url(r'^search/', include('haystack.urls')),
    url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
]

Actual Resource:

class AgoraUserResourse_min(ModelResource):
    username = fields.CharField(attribute = 'user__username' )
    class Meta:
        resource_name='user'
        #detail_uri_name = 'user__username'
        queryset = AgoraUser.objects.all()
        allowed_methods = ['get', 'put', 'post']
        authentication = AgoraAuthentication()
        authorization = AgoraAuthorization()
    def get_bundle_detail_data(self, bundle):
        return bundle.obj.username

Solution

  • It looks like you need to override detail_uri_kwargs for your resource.

    I wound up with something like this:

    from tastypie import fields
    from tastypie.resources import ModelResource
    from tastypie.bundle import Bundle
    
    from .models import AgoraUser
    
    
    class AgoraUserResourse(ModelResource):
        username = fields.CharField(attribute='user__username')
        class Meta:
            resource_name='user'
            detail_uri_name = 'user__username'
            queryset = AgoraUser.objects.all()
            allowed_methods = ['get', 'put', 'post']
            # authentication = AgoraAuthentication()
            # authorization = AgoraAuthorization()
    
        def detail_uri_kwargs(self, bundle_or_obj):
            if isinstance(bundle_or_obj, Bundle):
                bundle_or_obj = bundle_or_obj.obj
    
            return {
                'user__username': bundle_or_obj.user.username
            }
    
        def get_bundle_detail_data(self, bundle):
            return bundle.obj.username