2013-06-11 7 views
2

Я использую Django и tastypie для разработки REST API с первичным ключом, который является UUIDField из django_extensions. Однако, делая первичный ключ, UUID не играет хорошо с tastypie: когда я создаю ресурс с POST, URI, который он возвращает, является int, а не UUID, и предоставленный URI тогда неприменим, так как остальная часть API ожидает UUID для доступа к ресурсу.Tastypie не возвращает URI с UUID, когда UUIDField является первичным ключом

Я думаю, это связано с тем, что UUIDField только заменяет значение в UUIDField в pre_save Django, а tastypie возвращает заголовки до того, как это произойдет.

Я попытался написать пользовательский get_resource_uri для LocationResource, но объект, переданный в функцию, еще не имеет UUID (только обычный первичный ключ с автоматическим добавочным целым).

Как я могу получить tastypie, чтобы вернуть правильный UUID для ресурса? Есть ли лучший способ сделать pk UUID, что tastypie понравится лучше?

Модель:

from django.db import models 
from django_extensions.db.fields import UUIDField 

class Location(models.Model): 
    """ Stores information about a location. """ 

    id = UUIDField(primary_key=True) 
    path = models.TextField() 

    def __unicode__(self): 
     return "{uuid}: {path}".format(uuid=self.id, path=self.path) 

tastypie ModelResource (я до сих пор развивается локально, поэтому аутентификация и авторизация еще не настроен должным образом):

class LocationResource(ModelResource): 
    class Meta: 
     queryset = Location.objects.all() 
     authentication = Authentication() 
     authorization = Authorization() 

Что я вижу (JSON отформатирован для удобочитаемости):

$ curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"path": "/path/to/directory/"}' http://localhost:8000/api/v1/location/ 
HTTP/1.0 201 CREATED 
Date: Tue, 11 Jun 2013 19:59:07 GMT 
Server: WSGIServer/0.1 Python/2.7.3 
Vary: Accept 
X-Frame-Options: SAMEORIGIN 
Content-Type: text/html; charset=utf-8 
Location: http://localhost:8000/api/v1/location/1/ 

$ curl --dump-header - -H "Content-Type: application/json" -X GET http://localhost:8000/api/v1/location/1/ 
HTTP/1.0 404 NOT FOUND 
Date: Tue, 11 Jun 2013 19:59:27 GMT 
Server: WSGIServer/0.1 Python/2.7.3 
Vary: Accept 
X-Frame-Options: SAMEORIGIN 
Content-Type: text/html; charset=utf-8 

$ curl --dump-header - -H "Content-Type: application/json" -X GET http://localhost:8000/api/v1/location/ 
HTTP/1.0 200 OK 
Date: Tue, 11 Jun 2013 19:59:32 GMT 
Server: WSGIServer/0.1 Python/2.7.3 
Vary: Accept 
X-Frame-Options: SAMEORIGIN 
Content-Type: application/json 
Cache-Control: no-cache 

{"meta": 
    {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, 
"objects": [ 
    {"id": "5fe23dd4-d2d1-11e2-8566-94de802aa978", 
    "path": "/path/to/directory/", 
    "resource_uri": "/api/v1/location/5fe23dd4-d2d1-11e2-8566-94de802aa978/" 
    } 
    ] 
} 

ответ

1

Из моего опыта я бы не стал использовать UUID с django (в качестве первичного ключа). Возможно, некоторые умные люди приступили к работе, но я потратил несколько часов, пытаясь хорошо работать с uuids, но это настоящая головная боль. По умолчанию django ожидает, что первичные ключи будут целыми, а большинство расширений django делают одну и ту же презумпцию.

Tastypie использует основной резольвер django для генерации местоположения, поэтому проблема действительно не локализована для tastypie. Если вы хотите, чтобы UUID работали, вам, вероятно, нужно было бы развить django и внести свои изменения, что определенно не рекомендуется.

В конце дня, не имея вашего uuid в вашем URI, на самом деле не имеет большого значения. идея URI заключается в том, что его независимая от записи модели, то есть uri, не должна содержать первичный ключ модели. URI сам по себе является уникальным идентификатором ресурса (объект чтения), и поэтому вам не должно быть большой заботы о том, как он выглядит.

+0

Спасибо. Однажды я перестала пытаться первичными ключами UUID работать. Tastypie позволяет вам установить, что используется в URI, через 'detail_uri_name', и я сделал UUIDField уникальным, но не основным ключом, и все работало лучше. – Hwesta