Django - я не могу использовать модель фильтра Q с 2 связанными базами данных
У меня есть 2 следующие модели, связанные с 2 различными базами данных в models.py:
class AnalogicalValues(models.Model):
id = models.BigAutoField(primary_key=True)
date = models.DateField()
description = models.ForeignKey(ExpensesDescription, models.DO_NOTHING)
continent_id = models.ForeignKey(
'WorldContinent', db_column='continent_id', on_delete=models.DO_NOTHING
)
(...)hide code(...)
city_id = models.ForeignKey(
'WorldCity', db_column='city_id', verbose_name='City', on_delete=models.DO_NOTHING
)
value = models.FloatField()
comments = models.CharField(max_length=255, blank=True, null=True)
user_id = models.ForeignKey(User, db_column='user_id', on_delete=models.DO_NOTHING)
class Meta:
managed = False
db_table = 'analogical_values'
ordering = ('-date', '-id')
class WorldCity(models.Model):
id = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=255, verbose_name='City')
continent = models.ForeignKey(WorldContinent, models.DO_NOTHING)
country = models.ForeignKey(WorldCountry, models.DO_NOTHING)
subcountry = models.ForeignKey(WorldSubcountry, models.DO_NOTHING)
last_update_db = models.DateTimeField()
class Meta:
managed = False
db_table = 'cities'
ordering = ('name',)
verbose_name_plural = 'List of World Cities'
verbose_name = 'World City'
def __str__(self):
return self.name
Отношения между ними - city_id из AnalogicalValues и id из WorldCity, и каждая модель отображается на соответствующую базу данных в routers.py. Поле description в AnalogicalValues является foreignkey другой таблицы в той же базе данных, что и analogical_values, и все работает нормально.
class WorldRouter:
route_app_labels = {'myapp'}
route_model_list = {'WorldCity'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
class ExpensesRouter:
route_app_labels = {'myapp'}
route_model_list = {'AnalogicalValues'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
В models.py я хочу получить все результаты всех столбцов относительно строки, которую я пишу на форме 'filterData':
from . import models
from django.views import generic
class DataView(generic.ListView, generic.FormView):
(...some code...)
model = models.AnalogicalValues
paginate_by = 10
def get(self, *args, **kwargs):
(...some code...)
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__name__icontains=kwargs['filterData'])
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()
(...some code...)
return render(self.request, self.template_name, {
'datalist': datalist,
(...some args...)
})
Когда django доходит до строки self.paginate_by, я получаю эту ошибку
Я немного покопался и понял, что в запросе, который он строит, отсутствует имя базы данных для таблицы cities. Может ли кто-нибудь помочь мне с этим, пожалуйста? Спасибо
Exception Value: (1146, "Table 'EXPENSES.cities' doesn't exist")
Если вы прочитаете ваше исключение, легко увидеть, что таблица не существует. Возможно, сначала нужно сделать миграции.
Я знаю, что это не лучшая практика, но я сделал фильтр непосредственно из модели и захватил все идентификаторы для Q-фильтра, и это сработало
if kwargs['filterData']:
city_list = models.WorldCity.objects.filter(name__icontains=kwargs['filterData']).values()
city_id = []
[city_id.append(cur_city.get('id')) for cur_city in city_list]
else:
city_id = city_list.none()
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__id__in=city_id)
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()