mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-23 22:49:50 +03:00
Merge 9c72d2baad
into 303bc7cf95
This commit is contained in:
commit
9bd59d1e8f
|
@ -570,17 +570,17 @@ class HyperlinkedRelatedField(RelatedField):
|
|||
|
||||
kwargs = {self.slug_url_kwarg: slug}
|
||||
try:
|
||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
except:
|
||||
pass
|
||||
|
||||
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
||||
try:
|
||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
except:
|
||||
pass
|
||||
|
||||
raise ValidationError('Could not resolve URL for field using view name "%s"', view_name)
|
||||
raise ValidationError('Could not resolve URL for field using view name "%s"' % view_name)
|
||||
|
||||
def from_native(self, value):
|
||||
# Convert URL -> model instance pk
|
||||
|
@ -640,9 +640,11 @@ class HyperlinkedIdentityField(Field):
|
|||
slug_url_kwarg = None # Defaults to same as `slug_field` unless overridden
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# TODO: Make view_name mandatory, and have the
|
||||
# HyperlinkedModelSerializer set it on-the-fly
|
||||
self.view_name = kwargs.pop('view_name', None)
|
||||
try:
|
||||
self.view_name = kwargs.pop('view_name')
|
||||
except:
|
||||
raise ValueError("Hyperlinked Identity field requires 'view_name' kwarg")
|
||||
|
||||
self.format = kwargs.pop('format', None)
|
||||
|
||||
self.slug_field = kwargs.pop('slug_field', self.slug_field)
|
||||
|
@ -655,7 +657,7 @@ class HyperlinkedIdentityField(Field):
|
|||
def field_to_native(self, obj, field_name):
|
||||
request = self.context.get('request', None)
|
||||
format = self.format or self.context.get('format', None)
|
||||
view_name = self.view_name or self.parent.opts.view_name
|
||||
view_name = self.view_name
|
||||
kwargs = {self.pk_url_kwarg: obj.pk}
|
||||
try:
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
|
@ -669,13 +671,13 @@ class HyperlinkedIdentityField(Field):
|
|||
|
||||
kwargs = {self.slug_url_kwarg: slug}
|
||||
try:
|
||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
except:
|
||||
pass
|
||||
|
||||
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
||||
try:
|
||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from decimal import Decimal
|
|||
from django.db import models
|
||||
from django.forms import widgets
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from rest_framework.compat import get_concrete_model
|
||||
|
||||
# Note: We do the following so that users of the framework can use this style:
|
||||
|
@ -76,10 +77,34 @@ def _get_declared_fields(bases, attrs):
|
|||
|
||||
return SortedDict(fields)
|
||||
|
||||
def _get_options_instance(bases, attrs):
|
||||
options_class = Meta = None
|
||||
if '_options_class' in attrs:
|
||||
options_class = attrs['_options_class']
|
||||
else:
|
||||
for base in bases:
|
||||
if hasattr(base, '_options_class'):
|
||||
options_class = getattr(base, '_options_class')
|
||||
break
|
||||
if options_class is None:
|
||||
raise ImproperlyConfigured, 'A Serializer requires an "_options_class" attribute'
|
||||
|
||||
if 'Meta' in attrs:
|
||||
Meta = attrs['Meta']
|
||||
else:
|
||||
for base in bases:
|
||||
if hasattr(base, 'Meta'):
|
||||
Meta = getattr(base, 'Meta')
|
||||
break
|
||||
if Meta is None:
|
||||
raise ImproperlyConfigured, 'A Serializer requires an "Meta" attribute'
|
||||
|
||||
return options_class(Meta)
|
||||
|
||||
class SerializerMetaclass(type):
|
||||
def __new__(cls, name, bases, attrs):
|
||||
attrs['base_fields'] = _get_declared_fields(bases, attrs)
|
||||
attrs['opts'] = _get_options_instance(bases, attrs)
|
||||
return super(SerializerMetaclass, cls).__new__(cls, name, bases, attrs)
|
||||
|
||||
|
||||
|
@ -102,7 +127,6 @@ class BaseSerializer(Field):
|
|||
|
||||
def __init__(self, instance=None, data=None, files=None, context=None, partial=False, **kwargs):
|
||||
super(BaseSerializer, self).__init__(**kwargs)
|
||||
self.opts = self._options_class(self.Meta)
|
||||
self.parent = None
|
||||
self.root = None
|
||||
self.partial = partial
|
||||
|
@ -548,12 +572,14 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
|||
_options_class = HyperlinkedModelSerializerOptions
|
||||
_default_view_name = '%(model_name)s-detail'
|
||||
|
||||
url = HyperlinkedIdentityField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(HyperlinkedModelSerializer, self).__init__(*args, **kwargs)
|
||||
if self.opts.view_name is None:
|
||||
self.opts.view_name = self._get_default_view_name(self.opts.model)
|
||||
|
||||
if not 'url' in self.base_fields:
|
||||
self.base_fields.insert(0, 'url', HyperlinkedIdentityField(view_name=self.opts.view_name))
|
||||
|
||||
super(HyperlinkedModelSerializer, self).__init__(*args, **kwargs)
|
||||
|
||||
def _get_default_view_name(self, model):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user