Как передать в переменную только значение (строку), а не объект поля БД

Пишу Django проект про продажу/покупку автомобилей (как "Авто.ру" и "Авито").

Первоначальная цель: оптимизировать запросы к БД.

Проблема: После фильтрации объявлений по бренду, у всех объявлений одинаковый бренд. Поэтому запросы к БД у каждого объявления дублируются.

Цель: передать в переменную (какую-нибудь sorted_brand) строку названия бренда.

Сначала мой код, а потом то, что я перепробовал.

Вот мой код:

main_page.html

{% for obj in Ads %}

    <span>{{ obj.brand }}</span>
    <span>{{ obj.model }}</span>

{% endfor %}

FILTER/models.py

class Brand(models.Model):
    name = models.CharField(max_length=100, unique=True)

    def __str__(self):
        return self.name

class Model(models.Model):
    brand = models.ForeignKey('Brand', on_delete=models.CASCADE)
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

ADS/models.py

class Ads(models.Model):
    brand = models.ForeignKey(Brand,
                              on_delete=models.SET_NULL,
                              null=True,
                              verbose_name='Марка',
                              )
    model = models.ForeignKey(Model,
                              on_delete=models.SET_NULL,
                              null=True,
                              verbose_name='Модель',
                              )

ADS/views.py

def main_page(request):

    context = {
        'Ads': Ads.objects.all(),
        # Фильтрация происходит за кадром. 
        # Чтобы не усложнять поставил заглушку - Ads.objects.all().

        'Brand': Brand.objects.all(),
        'Model': Model.objects.all(),
    }

    return render(request, 'ADS/main_page.html', context)

Вот мои пробы:

main_page.html

{% for obj in Ads %}

    <span>{{ sorted_list.brand }}</span>
    <span>{{ obj.model }}</span>

{% endfor %}

ADS/views.py

sorted_list = None

    if request.POST:
        sorted_list = {
            'brand': [
                request.POST['brand'],
                Brand.objects.get(pk=request.POST['brand']),
                '',
            ],
        }

        for key, items in sorted_list.items():
            print(f'items - {items}')
            print()

            print(f'items[0] - {items[0]}')
            print(f'id(items[0]) - {id(items[0])}')
            print(f'type(items[0]) - {type(items[0])}')
            print()

            print(f'items[1] - {items[1]}')
            print(f'id(items[1]) - {id(items[1])}')
            print(f'type(items[1]) - {type(items[1])}')
            print()

            print(f'items[2] - {items[2]}')
            print(f'id(items[2]) - {id(items[2])}')
            print(f'type(items[2]) - {type(items[2])}')
            print()

            print(f'items[1] is items[2] - {items[1] is items[2]}')
            print()

            print('Конкатенация items[2] с str(items[1])')
            items[2] += str(items[1])
            print()

            print(f'items - {items}')
            print()

            print(f'items[0] - {items[0]}')
            print(f'id(items[0]) - {id(items[0])}')
            print(f'type(items[0]) - {type(items[0])}')
            print()

            print(f'items[1] - {items[1]}')
            print(f'id(items[1]) - {id(items[1])}')
            print(f'type(items[1]) - {type(items[1])}')
            print()

            print(f'items[2] - {items[2]}')
            print(f'id(items[2]) - {id(items[2])}')
            print(f'type(items[2]) - {type(items[2])}')
            print()

            print(f'items[1] is items[2] - {items[1] is items[2]}')
            print()

            print('Удаление items[0] и items[1]')
            del items[0]
            del items[1]
            print()

            print(f'items - {items}')
            print()

            print(f'items[0] - {items[0]}')
            print(f'id(items[0]) - {id(items[0])}')
            print(f'type(items[0]) - {type(items[0])}')


    context = {
        'Ads': Ads.objects.all(),
        'Brand': Brand.objects.all(),
        'Model': Model.objects.all(),

        'sorted_list': sorted_list,
    }

    return render(request, 'ADS/main_page.html', context)

Знаю, знаю. Это для наглядности, потому что природа происходящего мне не ясна. И вы тоже можете удивиться.

Вывод консоли после сортировки по бренду:

items - ['2', <Brand: BMW>, '']

    items[0] - 2
    id(items[0]) - 11819000
    type(items[0]) - <class 'str'>

    items[1] - BMW
    id(items[1]) - 138408491510928
    type(items[1]) - <class 'FILTER.models.Brand'>

    items[2] - 
    id(items[2]) - 11779312
    type(items[2]) - <class 'str'>

    items[1] is items[2] - False

Конкатенация items[2] с str(items[1])

items - ['2', <Brand: BMW>, 'BMW']

    items[0] - 2
    id(items[0]) - 11819000
    type(items[0]) - <class 'str'>

    items[1] - BMW
    id(items[1]) - 138408491510928
    type(items[1]) - <class 'FILTER.models.Brand'>

    items[2] - BMW
    id(items[2]) - 138408491506528
    type(items[2]) - <class 'str'>

    items[1] is items[2] - False

Удаление items[0] и items[1]

items - [<Brand: BMW>]

    items[0] - BMW
    id(items[0]) - 138408491510928
    type(items[0]) - <class 'FILTER.models.Brand'>

# Чтобы тебе легче глазами ориентироваться, понаставил отступов.

Что здесь произошло - к пустой строке прибавил значение объекта БД, и получилась строка с нужным значением (Ура). Удалил все остальные объекты в списке, кроме нужной строки, а она бац, стала объектом БД так ещё и с id объекта который был удалён (короче убитый мною объект вселился в нужный мне объект и преследует меня).

В процессе страстного гугления, я наткнулся на тему указателей. "В Python нет переменных, всё объекты и кругом имена бла-бла-бла". Понял, что на C, возможно, было бы проще сделать это.

Строго говоря, вопрос сильно глубже этого случая. Я хочу понять, как мне в переменную записать ТОЛЬКО значение из объекта, без ссылок на него (как copy.copy(), но оно не работает). Возможно я упускаю, что-то очевидное. Прошу мне на это указать.

Пожалуйста, помогите разобраться в механике происходящего. Буду рад ссылкам на то, где можно вычитать это.

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