Как передать в переменную только значение (строку), а не объект поля БД
Пишу 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(), но оно не работает). Возможно я упускаю, что-то очевидное. Прошу мне на это указать.
Пожалуйста, помогите разобраться в механике происходящего. Буду рад ссылкам на то, где можно вычитать это.