refactor the base classes a little (bug 846826)

This commit is contained in:
Andy McKay 2013-03-12 16:46:11 -07:00
Родитель f33f6c1b35
Коммит abf19083f9
6 изменённых файлов: 63 добавлений и 56 удалений

Просмотреть файл

@ -4,12 +4,12 @@ from tastypie.exceptions import ImmediateHttpResponse
from amo.urlresolvers import reverse
from mkt.api.authentication import (MarketplaceAuthentication,
OwnerAuthorization)
from mkt.api.base import MarketplaceResource
from mkt.api.base import MarketplaceModelResource
from mkt.constants.apps import INSTALL_TYPE_USER
from users.models import UserProfile
class AccountResource(MarketplaceResource):
class AccountResource(MarketplaceModelResource):
installed = fields.ListField('installed_list', readonly=True, null=True)
class Meta:

Просмотреть файл

@ -5,10 +5,9 @@ from django.core.exceptions import ObjectDoesNotExist
from tastypie import http
from tastypie.bundle import Bundle
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.resources import ModelResource
from tastypie.resources import Resource, ModelResource
import commonware.log
import oauth2
from translations.fields import PurifiedField, TranslatedField
log = commonware.log.getLogger('z.api')
@ -22,7 +21,47 @@ def get_url(name, pk):
return ('api_dispatch_detail', {'resource_name': name, 'pk': pk})
class MarketplaceResource(ModelResource):
class Marketplace(object):
"""
A mixin with some general Marketplace stuff.
"""
def dispatch(self, request_type, request, **kwargs):
# OAuth authentication uses the method in the signature. So we need
# to store the original method used to sign the request.
request.signed_method = request.method
if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
return (super(Marketplace, self)
.dispatch(request_type, request, **kwargs))
def form_errors(self, forms):
errors = {}
if not isinstance(forms, list):
forms = [forms]
for f in forms:
if isinstance(f.errors, list): # Cope with formsets.
for e in f.errors:
errors.update(e)
continue
errors.update(dict(f.errors.items()))
response = http.HttpBadRequest(json.dumps({'error_message': errors}),
content_type='application/json')
return ImmediateHttpResponse(response=response)
class MarketplaceResource(Marketplace, Resource):
"""
Use this if you would like to expose something that is *not* a Django
model as an API.
"""
pass
class MarketplaceModelResource(Marketplace, ModelResource):
"""Use this if you would like to expose a Django model as an API."""
def get_resource_uri(self, bundle_or_obj):
# Fix until my pull request gets pulled into tastypie.
@ -49,21 +88,6 @@ class MarketplaceResource(ModelResource):
return True if getattr(field, 'rel') else False
def form_errors(self, forms):
errors = {}
if not isinstance(forms, list):
forms = [forms]
for f in forms:
if isinstance(f.errors, list): # Cope with formsets.
for e in f.errors:
errors.update(e)
continue
errors.update(dict(f.errors.items()))
response = http.HttpBadRequest(json.dumps({'error_message': errors}),
content_type='application/json')
return ImmediateHttpResponse(response=response)
def get_object_or_404(self, cls, **filters):
"""
A wrapper around our more familiar get_object_or_404, for when we need
@ -86,27 +110,11 @@ class MarketplaceResource(ModelResource):
raise ImmediateHttpResponse(response=http.HttpNotFound())
return obj
def dispatch(self, request_type, request, **kwargs):
# OAuth authentication uses the method in the signature. So we need
# to store the original method used to sign the request.
request.signed_method = request.method
if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
try:
auth = (oauth2.Request._split_header(
request.META.get('HTTP_AUTHORIZATION', '')))
name = auth.get('oauth_consumer_key', 'none')
except (AttributeError, IndexError):
# Problems parsing the header.
name = 'error'
log.debug('%s:%s:%s' % (
request.META['REQUEST_METHOD'], request.path, name))
return (super(MarketplaceResource, self)
.dispatch(request_type, request, **kwargs))
class CORSResource(MarketplaceResource):
class CORSResource(object):
"""
A mixin to provide CORS support to your API.
"""
def method_check(self, request, allowed=None):
"""

Просмотреть файл

@ -23,7 +23,7 @@ from mkt.api.authentication import (AppOwnerAuthorization,
OptionalAuthentication,
OwnerAuthorization,
MarketplaceAuthentication)
from mkt.api.base import MarketplaceResource
from mkt.api.base import MarketplaceModelResource
from mkt.api.forms import (CategoryForm, DeviceTypeForm, NewPackagedForm,
PreviewArgsForm, PreviewJSONForm, StatusForm,
UploadForm)
@ -35,7 +35,7 @@ from reviews.models import Review
log = commonware.log.getLogger('z.api')
class ValidationResource(MarketplaceResource):
class ValidationResource(MarketplaceModelResource):
class Meta:
queryset = FileUpload.objects.all()
@ -98,7 +98,7 @@ class ValidationResource(MarketplaceResource):
return bundle
class AppResource(MarketplaceResource):
class AppResource(MarketplaceModelResource):
previews = fields.ToManyField('mkt.api.resources.PreviewResource',
'previews', readonly=True)
@ -226,7 +226,7 @@ class AppResource(MarketplaceResource):
return self._meta.queryset.filter(authors=request.amo_user)
class StatusResource(MarketplaceResource):
class StatusResource(MarketplaceModelResource):
class Meta:
queryset = Addon.objects.filter(type=amo.ADDON_WEBAPP)
@ -275,7 +275,7 @@ class StatusResource(MarketplaceResource):
return amo.STATUS_CHOICES_API_LOOKUP[int(bundle.data['status'])]
class CategoryResource(MarketplaceResource):
class CategoryResource(MarketplaceModelResource):
class Meta:
queryset = Category.objects.filter(type=amo.ADDON_WEBAPP,
@ -288,7 +288,7 @@ class CategoryResource(MarketplaceResource):
serializer = Serializer(formats=['json'])
class PreviewResource(MarketplaceResource):
class PreviewResource(MarketplaceModelResource):
image_url = fields.CharField(attribute='image_url', readonly=True)
thumbnail_url = fields.CharField(attribute='thumbnail_url', readonly=True)
@ -357,7 +357,7 @@ def collect_replies(bundle):
return Review.objects.filter(reply_to=bundle.obj.pk)
class RatingResource(MarketplaceResource):
class RatingResource(MarketplaceModelResource):
app = fields.ToOneField(AppResource, 'addon', readonly=True)
replies = fields.ToManyField('self', collect_replies,
@ -385,7 +385,7 @@ class RatingResource(MarketplaceResource):
ordering = ['created']
def get_object_list(self, request):
qs = MarketplaceResource.get_object_list(self, request)
qs = MarketplaceModelResource.get_object_list(self, request)
# Mature regions show only reviews from within that region.
if not request.REGION.adolescent:
qs = qs.filter(client_data__region=request.REGION.id)

Просмотреть файл

@ -17,7 +17,7 @@ from amo.tests import TestCase
from amo.helpers import urlparams
from amo.urlresolvers import reverse
from mkt.api.base import CORSResource
from mkt.api.base import CORSResource, MarketplaceResource
from mkt.api.models import Access, generate
from mkt.site.fixtures import fixture
@ -141,7 +141,7 @@ class BaseOAuth(TestCase):
return json.loads(response.content)['error_message']
class Resource(CORSResource):
class Resource(CORSResource, MarketplaceResource):
class Meta:
list_allowed_method = ['get']

Просмотреть файл

@ -5,14 +5,14 @@ from django.db import transaction
from mkt.api.authentication import (MarketplaceAuthentication,
PermissionAuthorization)
from mkt.api.base import MarketplaceResource
from mkt.api.base import MarketplaceModelResource
from .models import MonolithRecord
logger = logging.getLogger('z.monolith')
class MonolithData(MarketplaceResource):
class MonolithData(MarketplaceModelResource):
class Meta:
queryset = MonolithRecord.objects.all()

Просмотреть файл

@ -5,13 +5,13 @@ from amo.urlresolvers import reverse
from amo.utils import send_mail_jinja
from mkt.api.authentication import (PermissionAuthorization,
MarketplaceAuthentication)
from mkt.api.base import CORSResource, MarketplaceResource
from mkt.api.base import CORSResource, MarketplaceModelResource
from mkt.webpay.forms import FailureForm
from market.models import Price
from stats.models import Contribution
class PriceResource(CORSResource):
class PriceResource(CORSResource, MarketplaceModelResource):
prices = fields.ListField(attribute='prices', readonly=True)
localized = fields.DictField(attribute='suggested', readonly=True,
blank=True, null=True)
@ -23,7 +23,6 @@ class PriceResource(CORSResource):
resource_name = 'prices'
fields = ['name', 'suggested']
def _get_prices(self, bundle):
"""
Both localized and prices need access to this. But we whichever
@ -63,7 +62,7 @@ class PriceResource(CORSResource):
return self._get_prices(bundle)
class FailureNotificationResource(MarketplaceResource):
class FailureNotificationResource(MarketplaceModelResource):
class Meta:
queryset = Contribution.objects.filter(uuid__isnull=False)