通过外键在 Django 中过滤加入 table 的数据

Filtering data from joining table in Django by foreign key

我的模型 类 看起来像:

class Wine(models.Model):
    wine_id = models.IntegerField(blank=True, null=False, primary_key=True)
    wine_name = models.TextField(blank=True, null=True)
    wine_type = models.TextField(blank=True, null=True)
    wine_year = models.IntegerField(blank=True, null=True)
    wine_alcohol = models.FloatField(blank=True, null=True)
    wine_country = models.TextField(blank=True, null=True)
    wine_price = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'wine'

class Flavor(models.Model):
    flavor_id = models.IntegerField(primary_key=False)
    flavor_name = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'flavor'

还有一个连接 table 在这两者之间:

class FlavorWine(models.Model):
    flavor_wine_id = models.IntegerField(blank=True, null=False, primary_key=True)
    flavor_group = models.TextField(blank=True, null=True)
    flavor_count = models.IntegerField(blank=True, null=True)
    wine_id = models.ForeignKey('Wine', on_delete=models.DO_NOTHING)
    flavor_id = models.ForeignKey('Flavor', on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'flavor_wine'

现在,每当我尝试检索数据时都会出错。 我尝试在以下示例中使用:Django Filter by Foreign Key and ,但没有成功。

我试过了:

wines = Wine.objects.filter(wine_id=wine_id)
wine_flavor = FlavorWine.objects.filter(wine_id__in=wines.values('wine_id'))

return HttpResponse(serializers.serialize('json', wine_flavor, fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id')))

wine_flavor = serializers.serialize('json', FlavorWine.objects.filter(wine_id_id__gt=wine_id), fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id'))

wine_flavor = serializers.serialize('json', FlavorWine.objects.filter(wine_id__flavorwine__exact=wine_id), fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id'))

和提供的不同组合,但其中 none 有效,要么在加入 table 时失败,要么找不到所需的字段。 我总是得到提示:

提示:也许您打算引用列“flavor_wine.wine_id”。

我的意思是,这正是我要引用的专栏,但我找不到这样做的正确方法。

要从 ForeignKey 中过滤,您只需传递该模型的实例

在你第一个方法中:

wine_flavor = FlavorWine.objects.filter(wine_id__in=wines.values('wine_id'))

如果wine_idWine model的一个实例,那么你可以简单地写

 wine_flavor = FlavorWine.objects.filter(wine_id=wine_id)

并且如果 wine_id 是来自 Wine model 的 id 列表,那么您可以正确设置以下内容:

wine_flavor = FlavorWine.objects.filter(wine_id__id__in=wine_id)

让我解释一下上面一行的作用,

假设wine_id = ['1', '2', '3',....] 其中“1”代表 id 来自 Wine model

然后从 FlavorWine(FlavorWine.objects.filter)

中过滤那些

其中 id 来自 Wine model(wine_id__id) 在列表(wine_id)

(如果您需要更多帮助,请在下方评论,我可以相应地更新我的答案)

因此,为了通过外键在相关模型之间进行过滤,非常简单,方法是使用 prefetct_ralated 函数,该函数采用模型的相关名称作为参数。就像我下面的例子一样。这里有一个 link 阅读更多,以帮助您了解与预取相关的查询。 https://docs.djangoproject.com/en/4.0/ref/models/querysets/#prefetch-related

wines = Wine.objects.prefetch_related('flavorwine_set').filter(wine_id=wine_id)
wine_flavor = FlavorWine.objects.prefetch_related('flavorwine_set').filter(wine_id__in=wines.values('wine_id'))

试试这篇文章,https://www.django-antipatterns.com/antipattern/foreign-key-with-id-suffix.html 看看它是否能解决您的问题。

The main reason why it is a problem is because the .other_model itself does not store the id. Indeed, Django makes an implicit twin-field with an _id suffix that stores the primary key