在Django中选择相关

时间:2018-07-13 17:09:31

标签: django django-models django-rest-framework django-views

我正在尝试完成与以下内容类似的事情: How to join 3 tables in query with Django

基本上,我有3张桌子。在Django REST中,我们显示表3。如您在下面(models.py)所见,表3具有company_name,它是表2的外键,表2是表1的外键。和3通过表1 ID链接。表1包含了我们要在API输出中显示的实际文本,而不是ID号。

表1:汽车制造商-表2:汽车是什么-表3:所有汽车的清单

Models.py

Table 1:
class ManufacturerName(models.Model):
    name_id = models.AutoField(primary_key=True)
    company_name = models.CharField(unique=True, max_length=50)

    class Meta:
        managed = False
        db_table = 'manufacturer_name'

Table 2:
    class CarBuild(models.Model):
        car_id = models.AutoField(primary_key=True)
        car_icon = models.CharField(max_length=150, blank=True, null=True)
        company_name = models.ForeignKey('ManufacturerName', models.DO_NOTHING, db_column='ManufacturerName') 

        class Meta:
              managed = False
              db_table = 'car_build'

Table 3:
class CarList(models.Model):
    list_id = models.AutoField(primary_key=True)
    company_name = models.ForeignKey('CarBuild', models.DO_NOTHING, db_column='CarBuild')
    title = models.CharField(unique=True, max_length=100)
    description = models.TextField()


    class Meta:
        managed = False
        db_table = 'cars'

在我看来: 根据外键关系,这是我正在尝试的方法:

queryset = CarList.objects.all().select_related('company_name__company_name')

保存并运行它时,我没有收到任何错误,但是ID仍在返回,而不是与外键关系关联的文本:

[
    {
        "list_id": 1,
        "company_name": "http://127.0.0.1:8000/api/1/",
        "title": "Really fast car you're driving, and this is dummy text",

同样,我想实现从表1中获取与company_name外键关系相关联的文本以显示在JSON中。

序列化器和视图集

class manufacturer_name(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = manufacturer_name
        fields = ('name_id', 'company_name')

class manufacturer_name(viewsets.ModelViewSet):

    queryset = manufacturer_namee.objects.all()
    serializer_class = manufacturer_name


class CarBuildViewSet(viewsets.ModelViewSet):

    queryset = CarBuild.objects.all()
    serializer_class = CarBuildSerialiser

class CarBuildSerialiser(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = CarBuild
        fields = ('car_id', 'car_icon', 'company_name')


class CarListSerialiser(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = News
        fields = ('list_id', 'company_name', 'title')


class CarListViewSet(viewsets.ModelViewSet):
    serializer_class = CarList
    def get_queryset(self):
        queryset = News.objects.all().select_related('company_name__company_name')
    return queryset

1 个答案:

答案 0 :(得分:1)

基于详细的对话以清除一些细节。这是答案。

您需要对模型进行一些小的更改,因为这会使您难以理解要实现的目标。

型号:

class ManufacturerName(models.Model):
    name_id = models.AutoField(primary_key=True)
    company_name = models.CharField(unique=True, max_length=50)

    class Meta:
        managed = False
        db_table = 'manufacturer_name'


class CarBuild(models.Model):
    car_id = models.AutoField(primary_key=True)
    car_icon = models.CharField(max_length=150, blank=True, null=True)
    manufacturer = models.ForeignKey(ManufacturerName,on_delete=models.SET_NULL) 

    class Meta:
          managed = False
          db_table = 'car_build'


class CarList(models.Model):
    list_id = models.AutoField(primary_key=True)
    car = models.ForeignKey(CarBuild, on_delete=models.DO_NOTHING)
    title = models.CharField(unique=True, max_length=100)
    description = models.TextField()

    class Meta:
       managed = False
       db_table = 'cars'

然后您需要调整序列化器。

class CarListSerialiser(serializers.HyperlinkedModelSerializer):

    company_name= serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CarList
        fields =  ('list_id', 'company_name', 'title')

    def get_company_name(self, obj):
        return obj.car.manufacturer.company_name

然后在您的视图中使用它:

class CarListViewSet(viewsets.ModelViewSet):
    queryset = CarList.object.all()
    serializer_class = CarListSerialiser