首页 > 解决方案 > 我想在 Django Rest Framework 中获取 ForeignKey 的 url

问题描述

我有一个HyperlinkedModelSerializer带有 a 的模型ForeignKey,我想将超链接返回到该字段中引用的实例,但是我得到了嵌套在 json 中的整个对象。

这些是我的模型:

class Hotel(models.Model):

    ONE_STAR = '*'
    TWO_STARS = '**'
    THREE_STARS = '***'
    FOUR_STARS = '****'
    FIVE_STARS = '****'
    GRAND_TOURISM = 'GRAND_TOURISM'
    NA = 'NA'
    SPECIAL = 'SPECIAL'
    ECO = 'ECO'
    BOUTIQUE = 'BOUTIQUE'

    HOTEL_CATEGORY_CHOICES = (
        (ONE_STAR, _('*')),
        (TWO_STARS, _('**')),
        (THREE_STARS, _('***')),
        (FOUR_STARS, _('****')),
        (FIVE_STARS, _('*****')),
        (GRAND_TOURISM, _('Grand Tourism')),
        (NA, _('NA')),
        (SPECIAL, _('Special')),
        (ECO, _('Eco-Hotel')),
        (BOUTIQUE, _('Boutique-Hotel'))
    )

    company = models.OneToOneField(Company, on_delete=models.CASCADE, primary_key=True, verbose_name=_('Company'))
    code = models.CharField(max_length=10, verbose_name=_('Code'))
    city = models.ForeignKey(City, on_delete=models.PROTECT, related_name='hotels', verbose_name=_('City'))
    category = models.CharField(max_length=20, choices=HOTEL_CATEGORY_CHOICES, verbose_name=_('Category'))
    capacity = models.IntegerField(verbose_name=_('Capacity'))
    position = models.DecimalField(max_digits=11, decimal_places=2, default=0.00, verbose_name=_('Position'))
    in_pickup = models.BooleanField(default=False, verbose_name=_('In pickup?'))
    is_active = models.BooleanField(default=True, verbose_name=_('Is active?'))

    class Meta:
        verbose_name = _('Hotel')
        verbose_name_plural = _('Hotels')

    def __str__(self):
        return self.company.name

class Company(models.Model):
    name = models.CharField(max_length=40, verbose_name=_('Name'))
    legal_name = models.CharField(max_length=100, null=True, blank=True, verbose_name=_('Legal name'))
    tax_id = models.CharField(max_length=12, null=True, blank=True, verbose_name=_('Tax ID'))
    url = models.URLField(null=True, blank=True, verbose_name=_('URL'))
    address = models.TextField(max_length=400, null=True, blank=True, verbose_name=_('Address'))

    class Meta:
        verbose_name = _('Company')
        verbose_name_plural = _('Companies')

    def __str__(self):
        return "[{}]{}".format(self.id, self.name)

这是我的序列化器:

class HotelProductsSerializer(serializers.HyperlinkedModelSerializer):
    company = CompanySerializer()
    products = serializers.SerializerMethodField()

    def get_products(self, instance):
        queryset = [product for product in instance.company.products.all()]
        return ProductSerializer(queryset, many=True, context=self.context).data

    class Meta:
        model = models.Hotel
        fields = ('company', 'products')

这是我的视图集:

class HotelProductsViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Hotel.objects.all()
    serializer_class = serializers.HotelProductsSerializer

一切正常,但是该字段company会生成一个嵌套的 Company 对象,而我想获得指向该对象的超链接。

谢谢你的帮助。

标签: pythondjangodjango-rest-framework

解决方案


company字段被序列化为嵌套对象,因为您已使用嵌套序列化程序声明它。换线试试

company = CompanySerializer()

像这样的东西

company = serializers.HyperlinkedRelatedField(
    many=False,
    read_only=True
)

您可能需要根据文档调整选项。


推荐阅读