This commit is contained in:
Родитель
ab67ea55be
Коммит
41d8749043
|
@ -33,13 +33,13 @@ Detail
|
||||||
|
|
||||||
.. _collection-detail:
|
.. _collection-detail:
|
||||||
|
|
||||||
This endpoint allows you to fetch a single collection by its ``id`` or ``slug``.
|
This endpoint allows you to fetch a single collection by its ``slug``.
|
||||||
It returns any ``public`` collection by the specified user. You can access
|
It returns any ``public`` collection by the specified user. You can access
|
||||||
a non-``public`` collection only if it was authored by you, the authenticated user.
|
a non-``public`` collection only if it was authored by you, the authenticated user.
|
||||||
If your account has the `Collections:Edit` permission then you can access any collection.
|
If your account has the `Collections:Edit` permission then you can access any collection.
|
||||||
|
|
||||||
|
|
||||||
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/
|
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/
|
||||||
|
|
||||||
.. _collection-detail-object:
|
.. _collection-detail-object:
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ Filtering is as per :ref:`collection addon list endpoint<collection-addon-filter
|
||||||
Additional add-ons can be returned from the :ref:`Collection Add-on list endpoint<collection-addon-list>`.
|
Additional add-ons can be returned from the :ref:`Collection Add-on list endpoint<collection-addon-list>`.
|
||||||
|
|
||||||
|
|
||||||
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/?with_addons
|
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/?with_addons
|
||||||
|
|
||||||
.. _collection-detail-object-with-addons:
|
.. _collection-detail-object-with-addons:
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ Edit
|
||||||
This endpoint allows some of the details for a collection to be updated. Any fields
|
This endpoint allows some of the details for a collection to be updated. Any fields
|
||||||
in the :ref:`collection <collection-detail-object>` but not listed below are not editable and will be ignored in the patch request.
|
in the :ref:`collection <collection-detail-object>` but not listed below are not editable and will be ignored in the patch request.
|
||||||
|
|
||||||
.. http:patch:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/
|
.. http:patch:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/
|
||||||
|
|
||||||
.. _collection-edit-request:
|
.. _collection-edit-request:
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ Delete
|
||||||
|
|
||||||
This endpoint allows the collection to be deleted.
|
This endpoint allows the collection to be deleted.
|
||||||
|
|
||||||
.. http:delete:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/
|
.. http:delete:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ Collection Add-ons List
|
||||||
|
|
||||||
This endpoint lists the add-ons in a collection, together with collector's notes.
|
This endpoint lists the add-ons in a collection, together with collector's notes.
|
||||||
|
|
||||||
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/addons/
|
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/addons/
|
||||||
|
|
||||||
:query string filter: The :ref:`filter <collection-addon-filtering-param>` to apply.
|
:query string filter: The :ref:`filter <collection-addon-filtering-param>` to apply.
|
||||||
:query string sort: The sort parameter. The available parameters are documented in the :ref:`table below <collection-addon-list-sort>`.
|
:query string sort: The sort parameter. The available parameters are documented in the :ref:`table below <collection-addon-list-sort>`.
|
||||||
|
@ -199,7 +199,7 @@ Collection Add-ons Detail
|
||||||
|
|
||||||
This endpoint gets details of a single add-on in a collection, together with collector's notes.
|
This endpoint gets details of a single add-on in a collection, together with collector's notes.
|
||||||
|
|
||||||
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/addons/(int:addon_id|string:slug)/
|
.. http:get:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/addons/(int:addon_id|string:slug)/
|
||||||
|
|
||||||
.. _collection-addon-detail-object:
|
.. _collection-addon-detail-object:
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ Collection Add-ons Create
|
||||||
|
|
||||||
This endpoint allows a single add-on to be added to a collection, optionally with collector's notes.
|
This endpoint allows a single add-on to be added to a collection, optionally with collector's notes.
|
||||||
|
|
||||||
.. http:post:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/addons/
|
.. http:post:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/addons/
|
||||||
|
|
||||||
:<json string addon: The add-on id or slug to be added (required).
|
:<json string addon: The add-on id or slug to be added (required).
|
||||||
:<json string|object|null notes: The collectors notes for this item. (See :ref:`translated fields <api-overview-translations>`).
|
:<json string|object|null notes: The collectors notes for this item. (See :ref:`translated fields <api-overview-translations>`).
|
||||||
|
@ -238,7 +238,7 @@ Collection Add-ons Edit
|
||||||
|
|
||||||
This endpoint allows the collector's notes for single add-on to be updated.
|
This endpoint allows the collector's notes for single add-on to be updated.
|
||||||
|
|
||||||
.. http:patch:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/addons/(int:addon_id|string:slug)/
|
.. http:patch:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/addons/(int:addon_id|string:slug)/
|
||||||
|
|
||||||
:<json string|object|null notes: The collectors notes for this item. (See :ref:`translated fields <api-overview-translations>`).
|
:<json string|object|null notes: The collectors notes for this item. (See :ref:`translated fields <api-overview-translations>`).
|
||||||
|
|
||||||
|
@ -255,4 +255,4 @@ Collection Add-ons Delete
|
||||||
|
|
||||||
This endpoint allows a single add-on to be removed from a collection.
|
This endpoint allows a single add-on to be removed from a collection.
|
||||||
|
|
||||||
.. http:delete:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(int:id|string:collection_slug)/addons/(int:addon_id|string:slug)/
|
.. http:delete:: /api/v3/accounts/account/(int:user_id|string:username)/collections/(string:collection_slug)/addons/(int:addon_id|string:slug)/
|
||||||
|
|
|
@ -1410,6 +1410,20 @@ class TestCollectionViewSetDetail(TestCase):
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.data['id'] == self.collection.id
|
assert response.data['id'] == self.collection.id
|
||||||
|
|
||||||
|
def test_no_id_lookup(self):
|
||||||
|
collection = collection_factory(author=self.user, slug='999')
|
||||||
|
id_url = reverse(
|
||||||
|
'collection-detail', kwargs={
|
||||||
|
'user_pk': self.user.pk, 'slug': collection.id})
|
||||||
|
response = self.client.get(id_url)
|
||||||
|
assert response.status_code == 404
|
||||||
|
slug_url = reverse(
|
||||||
|
'collection-detail', kwargs={
|
||||||
|
'user_pk': self.user.pk, 'slug': collection.slug})
|
||||||
|
response = self.client.get(slug_url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.data['id'] == collection.id
|
||||||
|
|
||||||
def test_not_listed(self):
|
def test_not_listed(self):
|
||||||
self.collection.update(listed=False)
|
self.collection.update(listed=False)
|
||||||
|
|
||||||
|
@ -1513,25 +1527,6 @@ class TestCollectionViewSetDetail(TestCase):
|
||||||
unicode(addon.support_url))
|
unicode(addon.support_url))
|
||||||
|
|
||||||
|
|
||||||
class TestCollectionViewSetDetailWithId(TestCollectionViewSetDetail):
|
|
||||||
def _get_url(self, user, collection):
|
|
||||||
return reverse(
|
|
||||||
'collection-detail', kwargs={
|
|
||||||
'user_pk': user.pk, 'slug': collection.id})
|
|
||||||
|
|
||||||
def test_404(self):
|
|
||||||
# Invalid user.
|
|
||||||
response = self.client.get(reverse(
|
|
||||||
'collection-detail', kwargs={
|
|
||||||
'user_pk': self.user.pk + 66, 'slug': self.collection.id}))
|
|
||||||
assert response.status_code == 404
|
|
||||||
# Invalid collection.
|
|
||||||
response = self.client.get(reverse(
|
|
||||||
'collection-detail', kwargs={
|
|
||||||
'user_pk': self.user.pk, 'slug': '123456'}))
|
|
||||||
assert response.status_code == 404
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionViewSetDataMixin(object):
|
class CollectionViewSetDataMixin(object):
|
||||||
client_class = APITestClient
|
client_class = APITestClient
|
||||||
data = {
|
data = {
|
||||||
|
@ -1685,6 +1680,18 @@ class TestCollectionViewSetCreate(CollectionViewSetDataMixin, TestCase):
|
||||||
response = self.send(url=url)
|
response = self.send(url=url)
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
def test_create_numeric_slug(self):
|
||||||
|
self.client.login_api(self.user)
|
||||||
|
data = {
|
||||||
|
'name': u'this',
|
||||||
|
'slug': u'1',
|
||||||
|
}
|
||||||
|
response = self.send(data=data)
|
||||||
|
assert response.status_code == 201, response.content
|
||||||
|
collection = Collection.objects.get()
|
||||||
|
assert collection.name == data['name']
|
||||||
|
assert collection.slug == data['slug']
|
||||||
|
|
||||||
|
|
||||||
class TestCollectionViewSetPatch(CollectionViewSetDataMixin, TestCase):
|
class TestCollectionViewSetPatch(CollectionViewSetDataMixin, TestCase):
|
||||||
|
|
||||||
|
@ -1749,13 +1756,6 @@ class TestCollectionViewSetPatch(CollectionViewSetDataMixin, TestCase):
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
|
||||||
class TestCollectionViewSetPatchWithId(TestCollectionViewSetPatch):
|
|
||||||
def get_url(self, user):
|
|
||||||
return reverse(
|
|
||||||
'collection-detail', kwargs={
|
|
||||||
'user_pk': user.pk, 'slug': self.collection.id})
|
|
||||||
|
|
||||||
|
|
||||||
class TestCollectionViewSetDelete(TestCase):
|
class TestCollectionViewSetDelete(TestCase):
|
||||||
client_class = APITestClient
|
client_class = APITestClient
|
||||||
|
|
||||||
|
@ -1813,13 +1813,6 @@ class TestCollectionViewSetDelete(TestCase):
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
|
||||||
class TestCollectionViewSetDeleteWithId(TestCollectionViewSetDelete):
|
|
||||||
def get_url(self, user):
|
|
||||||
return reverse(
|
|
||||||
'collection-detail', kwargs={
|
|
||||||
'user_pk': user.pk, 'slug': self.collection.id})
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionAddonViewSetMixin(object):
|
class CollectionAddonViewSetMixin(object):
|
||||||
def check_response(self, response):
|
def check_response(self, response):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
@ -667,17 +667,7 @@ class CollectionViewSet(ModelViewSet):
|
||||||
AllOf(AllowReadOnlyIfPublic,
|
AllOf(AllowReadOnlyIfPublic,
|
||||||
PreventActionPermission('list'))),
|
PreventActionPermission('list'))),
|
||||||
]
|
]
|
||||||
lookup_url_kwarg = 'slug'
|
lookup_field = 'slug'
|
||||||
|
|
||||||
@property
|
|
||||||
def lookup_field(self):
|
|
||||||
identifier = self.kwargs.get(self.lookup_url_kwarg)
|
|
||||||
if identifier and identifier.isdigit():
|
|
||||||
lookup_field = 'pk'
|
|
||||||
else:
|
|
||||||
# If the identifier is anything other than a digit, it's the slug.
|
|
||||||
lookup_field = 'slug'
|
|
||||||
return lookup_field
|
|
||||||
|
|
||||||
def get_account_viewset(self):
|
def get_account_viewset(self):
|
||||||
if not hasattr(self, 'account_viewset'):
|
if not hasattr(self, 'account_viewset'):
|
||||||
|
|
Загрузка…
Ссылка в новой задаче