Как получить значение поля путем объединения нескольких наборов запросов в Django

Я пытаюсь отобразить изображения в списке на основе определенных условий.

Для этого я пытался создать queryset join из набора моделей (как показано ниже):

models.py

class ModeOfTransport(models.Model):
    mode_of_transport = models.CharField(unique=True, max_length=4...


class Route(models.Model):
    route_id = models.AutoField(primary_key=True)
    route_start = models.ForeignKey(City, related_name='route_start')
    route_end = models.ForeignKey(City, related_name='route_end')


class RouteLeg(models.Model):
    route_leg_id = models.AutoField(primary_key=True)
    route_id = models.ForeignKey(Route, related_name='route_hdr')
    leg_start = models.ForeignKey(City, related_name='leg_start')
    leg_end = models.ForeignKey(City, related_name='leg_start')
    mode_of_tptn = models.ForeignKey(ModeOfTransport, related_name='route_tptn_mode')


class ImageType(models.Model):
    image_type_id = models.CharField(primary_key=True, max_length=1)
    image_type = models.CharField(max_length=4)


class RouteImage(models.Model):
    image_id = models.AutoField(primary_key=True)
    image_name = models.CharField(max_length=125)
    image_type = models.ForeignKey(ImageType)
    image_route = models.ImageField(upload_to='images/route_images/')

Из списка существующих маршрутов (общий вид списка) я пытаюсь создать дальнейшее раскрытие списка следующим образом:

views.py

def graf_display_route(request, pk):
    if request.method == 'GET':
        route_grafiks = RouteLeg.objects.all().filter(route_id=pk)
        return render(request, 'route_grafiks.html', {'route_grafiks': route_grafiks})

Теперь, чтобы добраться до поля изображения (RouteImage.image_route), я попробовал следующее, чтобы получить image_type и затем само изображение:

qs_mode_of_tptn = ImageType.objects.filter(image_type_id__in= route_graphics.values_list('mode_of_tptn', flat=True))

Результат (при печати списка результирующего кверисета) я могу увидеть в терминале как:

[<ImageType: ImageType object (2)>, <ImageType: ImageType object (3)>]>

Далее, используя кверисет qs_mode_of_tptn когда я использую другой qset, я получаю поля таблицы изображений (модель "RouteImage"):

qs_route_image = RouteImage.objects.filter(image_id__in= qs_mode_of_tptn.values_list('image_type_id', flat=True))

Вот что я получаю в терминале:

[<RouteImage: RouteImage object (2)>, <RouteImage: RouteImage object (3)>]>

Цель моей работы - выяснить как получить изображение из модели RouteImage на основе результата queryset.

Чтобы уточнить, я сделал отображение для изображений следующим образом:

Field Road Rail Air
MoT (Mode of Transportation) 1 2 3
Image Type 1 2 3

Моя цель состоит в том, чтобы искать изображение следующим образом:

Get the "MoT (Model - RouteLeg)" -> Get "Image Type (Model - ImageType)" -> Get the "Image (Model - RouteImage)"

Итак, если MoT - Road (1), получите ImageType (со значением "1"), а затем получите RouteImage (для image_type == 1).

Могу ли я действительно получить изображения по вышеописанному сценарию? Если нет, то не могли бы вы предложить способ сделать именно это.

Вы можете построить dict с image_type в качестве ключа, чтобы можно было сопоставить изображения с определенным видом транспорта. Обратите внимание, что если вы используете select_related() для mode_of_tptn, Django уже присоединится к соответствующей таблице, поэтому дополнительных поисков не будет. Чтобы получить изображения по типу, вы можете использовать запрос, охватывающий отношения .

# your view
def graf_display_route(request, pk):
    if request.method == 'GET':
        route_grafiks_qs = RouteLeg.objects.all().filter(route_id=pk).select_related("mode_of_tptn")
        
        # build a list of the modes of transport without additional query
        modes_of_tpn = [rg.mode_of_tptn.mode_of_transport for rg in route_grafiks_qs]

        # filter images for image type
        image_qs = RouteImage.objects.in_bulk(image_type__image_type__in=modes_of_tpn)
        # build a dict of images with type as key
        images = {i.image_type.image_type: i for i in image_qs}

        route_grafiks = []
        for rg in route_grafiks:
            rg.image = images[rg.mode_of_tptn.mode_of_transport]
            route_grafiks.append(rg)

        return render(request, 'route_grafiks.html', {
            'route_grafiks': route_grafiks,
        })

# in your template
{% for r in route_grafiks %}
    {{ r.image }}
{% endfor %}

Вернуться на верх