给出以下模型:
class Places(models.Model):
#...
class Tour(models.Model):
places = ManyToManyField(A, through='TourPlaces')
class TourPlaces(models.Model):
tour = ForeignKey(Tour, on_delete=models.CASCADE)
place = ForeignKey(Place, on_delete=models.CASCADE)
#...
如何构建查询集,以便可以在SQL端获取Places所属的Tours,而又不必反复访问数据库?伪示例:
for place in Places.objects.(some kind of annotation maybe?):
print(place.tours[0])
代替
for place in Places.objects.all():
print(TourPlaces.objects.get(place=place).tour[0])
上下文:使用上面在SerializerMethodField中的代码,我的REST Framework ModelSerializer for Places太慢了。
答案 0 :(得分:0)
class Places(models.Model):
first_field = models.CharField(max_length=50)
second_field = models.CharField(max_length=50)
class Tour(models.Model):
places = ManyToManyField(A, through='TourPlaces')
class TourPlaces(models.Model):
tour = ForeignKey(Tour, on_delete=models.CASCADE)
place = ForeignKey(Place, on_delete=models.CASCADE)
然后:
TourPlaces.objects.filter(place__first_field = 'some')
答案 1 :(得分:0)
我通过使用带有反向集的prefetch_related解决了这个问题并提高了性能:
for place in Places.objects.prefetch_related('tour_set').all():
print(str(place.tour_set.first()))
请参见https://docs.djangoproject.com/en/2.1/ref/models/querysets/#prefetch-related
我的REST视图集和模型序列化器现在看起来像这样:
class PlaceViewSet(viewsets.ModelViewSet):
parser_classes = (JSONParser,)
serializer_class = PlaceSerializer
queryset = Place.objects.prefetch_related('tour_set')
class PlaceSerializer(serializers.ModelSerializer):
tour = serializers.SerializerMethodField('_tour')
def _tour(self, obj):
try:
return str(obj.tour_set.first())
except:
return ""
class Meta:
model = Place
fields = (
'...',
'tour',
)