mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-23 14:40:06 +03:00
Merge bf77a92c66
into 647abcdb16
This commit is contained in:
commit
b66bab3349
|
@ -504,6 +504,7 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
except:
|
except:
|
||||||
raise ValueError("Hyperlinked field requires 'view_name' kwarg")
|
raise ValueError("Hyperlinked field requires 'view_name' kwarg")
|
||||||
|
|
||||||
|
self.view_namespace = kwargs.pop('view_namespace',None)
|
||||||
self.slug_field = kwargs.pop('slug_field', self.slug_field)
|
self.slug_field = kwargs.pop('slug_field', self.slug_field)
|
||||||
default_slug_kwarg = self.slug_url_kwarg or self.slug_field
|
default_slug_kwarg = self.slug_url_kwarg or self.slug_field
|
||||||
self.pk_url_kwarg = kwargs.pop('pk_url_kwarg', self.pk_url_kwarg)
|
self.pk_url_kwarg = kwargs.pop('pk_url_kwarg', self.pk_url_kwarg)
|
||||||
|
@ -519,7 +520,13 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
return self.slug_field
|
return self.slug_field
|
||||||
|
|
||||||
def to_native(self, obj):
|
def to_native(self, obj):
|
||||||
view_name = self.view_name
|
if self.view_namespace:
|
||||||
|
view_name = "%(namespace)s:%(view)s" % {
|
||||||
|
'view':self.view_name,
|
||||||
|
'namespace':self.view_namespace
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
view_name = self.view_name
|
||||||
request = self.context.get('request', None)
|
request = self.context.get('request', None)
|
||||||
format = self.format or self.context.get('format', None)
|
format = self.format or self.context.get('format', None)
|
||||||
pk = getattr(obj, 'pk', None)
|
pk = getattr(obj, 'pk', None)
|
||||||
|
@ -538,13 +545,13 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
|
|
||||||
kwargs = {self.slug_url_kwarg: slug}
|
kwargs = {self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -611,6 +618,7 @@ class HyperlinkedIdentityField(Field):
|
||||||
# TODO: Make view_name mandatory, and have the
|
# TODO: Make view_name mandatory, and have the
|
||||||
# HyperlinkedModelSerializer set it on-the-fly
|
# HyperlinkedModelSerializer set it on-the-fly
|
||||||
self.view_name = kwargs.pop('view_name', None)
|
self.view_name = kwargs.pop('view_name', None)
|
||||||
|
self.view_namespace = kwargs.pop('view_namespace', None)
|
||||||
self.format = kwargs.pop('format', None)
|
self.format = kwargs.pop('format', None)
|
||||||
|
|
||||||
self.slug_field = kwargs.pop('slug_field', self.slug_field)
|
self.slug_field = kwargs.pop('slug_field', self.slug_field)
|
||||||
|
@ -623,7 +631,13 @@ class HyperlinkedIdentityField(Field):
|
||||||
def field_to_native(self, obj, field_name):
|
def field_to_native(self, obj, field_name):
|
||||||
request = self.context.get('request', None)
|
request = self.context.get('request', None)
|
||||||
format = self.format or self.context.get('format', None)
|
format = self.format or self.context.get('format', None)
|
||||||
|
view_namespace = self.view_namespace or self.parent.opts.view_namespace
|
||||||
view_name = self.view_name or self.parent.opts.view_name
|
view_name = self.view_name or self.parent.opts.view_name
|
||||||
|
if view_namespace:
|
||||||
|
view_name = "%(namespace)s:%(view)s" % {
|
||||||
|
'view':view_name,
|
||||||
|
'namespace':view_namespace
|
||||||
|
}
|
||||||
kwargs = {self.pk_url_kwarg: obj.pk}
|
kwargs = {self.pk_url_kwarg: obj.pk}
|
||||||
try:
|
try:
|
||||||
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
|
@ -637,13 +651,13 @@ class HyperlinkedIdentityField(Field):
|
||||||
|
|
||||||
kwargs = {self.slug_url_kwarg: slug}
|
kwargs = {self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,22 @@ class BrowsableAPIRenderer(BaseRenderer):
|
||||||
media_type = 'text/html'
|
media_type = 'text/html'
|
||||||
format = 'api'
|
format = 'api'
|
||||||
template = 'rest_framework/api.html'
|
template = 'rest_framework/api.html'
|
||||||
|
field_mapping = {
|
||||||
|
serializers.FloatField: forms.FloatField,
|
||||||
|
serializers.IntegerField: forms.IntegerField,
|
||||||
|
serializers.DateTimeField: forms.DateTimeField,
|
||||||
|
serializers.DateField: forms.DateField,
|
||||||
|
serializers.EmailField: forms.EmailField,
|
||||||
|
serializers.CharField: forms.CharField,
|
||||||
|
serializers.ChoiceField: forms.ChoiceField,
|
||||||
|
serializers.BooleanField: forms.BooleanField,
|
||||||
|
serializers.PrimaryKeyRelatedField: forms.ChoiceField,
|
||||||
|
serializers.ManyPrimaryKeyRelatedField: forms.MultipleChoiceField,
|
||||||
|
serializers.SlugRelatedField: forms.ChoiceField,
|
||||||
|
serializers.ManySlugRelatedField: forms.MultipleChoiceField,
|
||||||
|
serializers.HyperlinkedRelatedField: forms.ChoiceField,
|
||||||
|
serializers.ManyHyperlinkedRelatedField: forms.MultipleChoiceField
|
||||||
|
}
|
||||||
|
|
||||||
def get_default_renderer(self, view):
|
def get_default_renderer(self, view):
|
||||||
"""
|
"""
|
||||||
|
@ -306,22 +322,6 @@ class BrowsableAPIRenderer(BaseRenderer):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def serializer_to_form_fields(self, serializer):
|
def serializer_to_form_fields(self, serializer):
|
||||||
field_mapping = {
|
|
||||||
serializers.FloatField: forms.FloatField,
|
|
||||||
serializers.IntegerField: forms.IntegerField,
|
|
||||||
serializers.DateTimeField: forms.DateTimeField,
|
|
||||||
serializers.DateField: forms.DateField,
|
|
||||||
serializers.EmailField: forms.EmailField,
|
|
||||||
serializers.CharField: forms.CharField,
|
|
||||||
serializers.ChoiceField: forms.ChoiceField,
|
|
||||||
serializers.BooleanField: forms.BooleanField,
|
|
||||||
serializers.PrimaryKeyRelatedField: forms.ChoiceField,
|
|
||||||
serializers.ManyPrimaryKeyRelatedField: forms.MultipleChoiceField,
|
|
||||||
serializers.SlugRelatedField: forms.ChoiceField,
|
|
||||||
serializers.ManySlugRelatedField: forms.MultipleChoiceField,
|
|
||||||
serializers.HyperlinkedRelatedField: forms.ChoiceField,
|
|
||||||
serializers.ManyHyperlinkedRelatedField: forms.MultipleChoiceField
|
|
||||||
}
|
|
||||||
|
|
||||||
fields = {}
|
fields = {}
|
||||||
for k, v in serializer.get_fields(True).items():
|
for k, v in serializer.get_fields(True).items():
|
||||||
|
@ -347,7 +347,7 @@ class BrowsableAPIRenderer(BaseRenderer):
|
||||||
kwargs['label'] = k
|
kwargs['label'] = k
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fields[k] = field_mapping[v.__class__](**kwargs)
|
fields[k] = self.field_mapping[v.__class__](**kwargs)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if getattr(v, 'choices', None) is not None:
|
if getattr(v, 'choices', None) is not None:
|
||||||
fields[k] = forms.ChoiceField(**kwargs)
|
fields[k] = forms.ChoiceField(**kwargs)
|
||||||
|
|
|
@ -490,6 +490,7 @@ class HyperlinkedModelSerializerOptions(ModelSerializerOptions):
|
||||||
def __init__(self, meta):
|
def __init__(self, meta):
|
||||||
super(HyperlinkedModelSerializerOptions, self).__init__(meta)
|
super(HyperlinkedModelSerializerOptions, self).__init__(meta)
|
||||||
self.view_name = getattr(meta, 'view_name', None)
|
self.view_name = getattr(meta, 'view_name', None)
|
||||||
|
self.view_namespace = getattr(meta, 'view_namespace', None)
|
||||||
|
|
||||||
|
|
||||||
class HyperlinkedModelSerializer(ModelSerializer):
|
class HyperlinkedModelSerializer(ModelSerializer):
|
||||||
|
@ -497,6 +498,7 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
||||||
"""
|
"""
|
||||||
_options_class = HyperlinkedModelSerializerOptions
|
_options_class = HyperlinkedModelSerializerOptions
|
||||||
_default_view_name = '%(model_name)s-detail'
|
_default_view_name = '%(model_name)s-detail'
|
||||||
|
_default_view_namespace = None # default: no namespace is prepend to view_name
|
||||||
|
|
||||||
url = HyperlinkedIdentityField()
|
url = HyperlinkedIdentityField()
|
||||||
|
|
||||||
|
@ -504,6 +506,8 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
||||||
super(HyperlinkedModelSerializer, self).__init__(*args, **kwargs)
|
super(HyperlinkedModelSerializer, self).__init__(*args, **kwargs)
|
||||||
if self.opts.view_name is None:
|
if self.opts.view_name is None:
|
||||||
self.opts.view_name = self._get_default_view_name(self.opts.model)
|
self.opts.view_name = self._get_default_view_name(self.opts.model)
|
||||||
|
if self.opts.view_namespace is None:
|
||||||
|
self.opts.view_namespace = self._get_default_view_namespace(self.opts.model)
|
||||||
|
|
||||||
def _get_default_view_name(self, model):
|
def _get_default_view_name(self, model):
|
||||||
"""
|
"""
|
||||||
|
@ -516,6 +520,20 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
||||||
}
|
}
|
||||||
return self._default_view_name % format_kwargs
|
return self._default_view_name % format_kwargs
|
||||||
|
|
||||||
|
def _get_default_view_namespace(self, model):
|
||||||
|
"""
|
||||||
|
Return the view namespace to use if 'view_namespace' is not specified in 'Meta'
|
||||||
|
"""
|
||||||
|
if self._default_view_namespace is None:
|
||||||
|
return self._default_view_namespace
|
||||||
|
|
||||||
|
model_meta = model._meta
|
||||||
|
format_kwargs = {
|
||||||
|
'app_label': model_meta.app_label,
|
||||||
|
'model_name': model_meta.object_name.lower()
|
||||||
|
}
|
||||||
|
return self._default_view_namespace % format_kwargs
|
||||||
|
|
||||||
def get_pk_field(self, model_field):
|
def get_pk_field(self, model_field):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -529,7 +547,8 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
||||||
queryset = rel._default_manager
|
queryset = rel._default_manager
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'queryset': queryset,
|
'queryset': queryset,
|
||||||
'view_name': self._get_default_view_name(rel)
|
'view_name': self._get_default_view_name(rel),
|
||||||
|
'view_namespace': self._get_default_view_namespace(rel)
|
||||||
}
|
}
|
||||||
if to_many:
|
if to_many:
|
||||||
return ManyHyperlinkedRelatedField(**kwargs)
|
return ManyHyperlinkedRelatedField(**kwargs)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user