模型字段名为url和django rest框架url

时间:2013-08-14 12:33:58

标签: django django-rest-framework

几天前我开始使用伟大的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"
        }

我该如何解决? 感谢

6 个答案:

答案 0 :(得分:6)

它可能被认为是糟糕的形式(我绝不是专业程序员或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'作为您的来源会导致问题,您可能想要将您的模型字段命名为其他内容 - 如果是这样的话我会道歉并且我浪费了你的时间。

希望我有所帮助。

答案 1 :(得分:3)

在DRF 3中,我接受的答案对我不起作用。我获得了urlurl的模型url_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应替换为与单个帐户对应的任何视图。

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:0)

避免冲突的最简单方法是在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 
}

答案 4 :(得分:0)

以上答案并不精确。仅通过使用“ 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)

答案 5 :(得分:-1)

需要正确配置Nginx,将你的ip放入PROXY_PASS

<script type="text/javascript" src="http://intranet/sites/hr/js/js/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
    $('#accordion > li').hover(
        function () {
            var $this = $(this);
            $this.stop().animate({'width':'400px'},400);
            $('.heading',$this).stop(true,true).fadeOut();
            $('.bgDescription',$this).stop(true,true).slideDown(400);
            $('.description',$this).stop(true,true).fadeIn();
        },
        function () {
            var $this = $(this);
            $this.stop().animate({'width':'125px'},1000);
            $('.heading',$this).stop(true,true).fadeIn();
            $('.description',$this).stop(true,true).fadeOut(400);
            $('.bgDescription',$this).stop(true,true).slideUp(600);
        }
    );
});
</script>

http://127.0.0.1:8003

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