6

几天前我开始使用很棒的 django-rest-framework。我无法解决这个简单的问题。

我的模型包含一个名为 url 的 models.URLField。

我的 serializers.py 文件:

class ModelSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.Field(source='owner.username')    

    class Meta:
        model = Model
        fields = ('url', 'owner', 'title', 'abstract', 'category', 'position', 'param1')

检查 API 结果,字段“url”填充了 model.URLField。

"results": [
        {
            "url": "http://www.web.com", 
            "owner": "me", 
            "title": "title of the stuff"
        }

相反,我想拥有

"results": [
        {
            "url": "http://localhost:8000/en/apiv1/maps/4/", 
            "url_in_model": "http://www.web.com", 
            "owner": "me", 
            "title": "Forest fire"
        }

我该如何解决?谢谢

4

6 回答 6

9

它可能被认为是糟糕的形式(我绝不是专业程序员或 rest_framework 专家),但我相信您可以为序列化输出添加额外的上下文:

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

额外的字段可以对应于模型上的任何属性或可调用的。


所以在上面的字段'get_absolute_url'必须在'Account'模型中。在你的情况下(我认为)你可以这样做:

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')

当然,您会选择适合的字段类型。

我没有机会对此进行测试,因此使用“url”作为您的来源可能会导致问题,您可能想将您的模型字段命名为其他名称 - 如果是这种情况,请道歉,我已经浪费了您的时间。

希望我有所帮助。

于 2013-11-26T10:26:23.680 回答
5

在 DRF 3 中,接受的答案对我不起作用。我得到了模型的url数据urlurl_in_model。为了从 DRF 中获取正确的url值,它看起来像:

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='account-detail')
    url_in_model = serializer.URLField(source='url')  

    class Meta:
        model = Account

account-detail应替换为对应于单个帐户的任何视图。

于 2015-04-15T12:44:36.273 回答
4

我个人更喜欢将默认的超链接字段设置为另一个名称。

您可以通过URL_FIELD_NAME设置执行此操作。

来源: http: //www.django-rest-framework.org/api-guide/serializers/#sharing-the-url-field-name

例如:(URL_FIELD_NAME = 'key'默认为'url')

于 2017-06-24T13:54:42.153 回答
2

避免冲突的最简单方法是设置URL_FIELD_NAME如下settings.py

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 
}
于 2018-11-05T03:19:58.290 回答
1

上面的答案并不准确。它只是通过使用“url_field_name”键来控制url的名称(默认为'url')。

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

serializer.py 中 ModelSerializer 的源代码

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)
于 2020-10-07T14:18:10.370 回答
-2

Nginx需要正确配置,把你的ip放在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;
}

将http://127.0.0.1:8003更改为http://this-is-my-ip-address.com/[port]

于 2015-10-02T06:14:55.537 回答