Reputation: 791
I started to use the great django-rest-framework days ago. I'm not able to solve this simple issue.
My model contains a models.URLField named url.
My serializers.py file:
class ModelSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.Field(source='owner.username')
class Meta:
model = Model
fields = ('url', 'owner', 'title', 'abstract', 'category', 'position', 'param1')
Checking the API result the field 'url' is populated with model.URLField.
"results": [
{
"url": "http://www.web.com",
"owner": "me",
"title": "title of the stuff"
}
Instead I would like to have
"results": [
{
"url": "http://localhost:8000/en/apiv1/maps/4/",
"url_in_model": "http://www.web.com",
"owner": "me",
"title": "Forest fire"
}
How can I solve? Thanks
Upvotes: 6
Views: 3882
Reputation: 380
class UserSerializer(serializers.ModelSerializer):
url_field_name='test-url'
class Meta:
model = UserInfo
extra_kwargs = {
'test-url': {
'view_name': '<your view name defined on urls.py>',
'lookup_field': '<lookup_field>',
'lookup_url_kwarg': '<lookup_url_kwarg>'
}
}
fields = ['test-url'] #remember include your defined url name
def get_fields(self):
"""
Return the dict of field names -> field instances that should be
used for `self.fields` when instantiating the serializer.
"""
if self.url_field_name is None:
self.url_field_name = api_settings.URL_FIELD_NAME
assert hasattr(self, 'Meta'), (
'Class {serializer_class} missing "Meta" attribute'.format(
serializer_class=self.__class__.__name__
)
)
assert hasattr(self.Meta, 'model'), (
'Class {serializer_class} missing "Meta.model" attribute'.format(
serializer_class=self.__class__.__name__
)
)
if model_meta.is_abstract_model(self.Meta.model):
raise ValueError(
'Cannot use ModelSerializer with Abstract Models.'
)
declared_fields = copy.deepcopy(self._declared_fields)
model = getattr(self.Meta, 'model')
depth = getattr(self.Meta, 'depth', 0)
Upvotes: 1
Reputation: 1258
The easiest way to avoid the conflict is to set URL_FIELD_NAME
in settings.py
like:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.BasicAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
"URL_FIELD_NAME": "api_url", // <---- add this
}
Upvotes: 2
Reputation: 545
I personally prefer to set the default hyperlinked field to another name altogether.
You can do this via the URL_FIELD_NAME
setting.
Source: http://www.django-rest-framework.org/api-guide/serializers/#changing-the-url-field-name
e.g: URL_FIELD_NAME = 'key'
(default is 'url')
Upvotes: 4
Reputation: 147
Nginx needs to be configured correctly, put your ip in the PROXY_PASS
location / {
proxy_pass http://127.0.0.1:8003;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
}
Change http://127.0.0.1:8003 by http://this-is-my-ip-address.com/[port]
Upvotes: -2
Reputation: 937
The accepted answer didn't work for me in DRF 3. I got my model's url
data for both url
and url_in_model
. To get the correct url
value from DRF, it looked like:
class AccountSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='account-detail')
url_in_model = serializer.URLField(source='url')
class Meta:
model = Account
account-detail
should be replaced with whatever view corresponds to a single Account.
Upvotes: 5
Reputation: 116
It may be considered poor form (I am by no means a pro programmer or rest_framework expert), but I believe you can add extra context to the serialized output:
http://django-rest-framework.org/api-guide/serializers.html#specifying-fields-explicitly
class AccountSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
groups = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Account
Extra fields can correspond to any property or callable on the model.
So in the above the field 'get_absolute_url' must be in the 'Account' model. In your case (I think) you could do this:
class ModelSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.Field(source='owner.username')
url_in_model = serializer.Field(source='url')
class Meta:
model = Model
fields = ('url', 'url_in_model', 'owner', 'title', 'abstract', 'category', 'position', 'param1')
Of course you would pick the field type that suits.
I haven't had the chance to test this, so there is the chance that using 'url' as your source causes an issue and you may want to name your model field something else - apologies if that is the case and I have wasted your time.
Hope I have helped.
Upvotes: 9