Поэтому у меня есть следующие модели структуры в моей Django App: -Джанго/SQL - Создание представления в виде таблицы, которая соединяет таблицу с таблицей коррекции
class SuperModel(models.Model):
f1 = models.CharField()
f2 = models.CharField()
class Model(SuperModel):
f3 = models.CharField()
class OverrideModel(models.Model):
fpk = models.OneToOneField(Model, primary_key=True)
f1 = models.CharField()
f2 = models.CharField()
В принципе, в моем приложении, поля f1
и f2
в таблице Model
содержатся данные пользователя, которые я ввел. Пользователь может переопределить эту информацию, и любые изменения, которые он делает в данных, хранятся в таблице OverrideModel
(потому что я не хочу потерять информацию, которую я ввел первым). Подумайте об этом, поскольку я сначала создаю пользовательские профили, а теперь хочу, чтобы пользователь мог редактировать свой профиль, не теряя информацию, которую я ввел в них.
Теперь, так как остальная часть моего приложения (просмотр/шаблоны идр) работают с именами полей в классе модели, что я хочу, чтобы создать вид данных, который извлекает поле f1
из таблицы переназначения если он существует, в противном случае он должен забрать f1
из таблицы, которая использовалась ранее без, прибегая к необработанному набору запросов.
Я буду описывать все, что я считал до сих пор так, что некоторые из других ограничений, с которыми я работаю стало ясно: -
Model.objects.annotate(f1=Case(When(overridemodel__f1__isnull=True, then=F('f1')), default=F('overridemodel__f1')))
.Это приводит к ошибке, связанной с тем, что аннотированный псевдоним конфликтует с полем, уже находящимся в таблице.
Model.objects.defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...)
.Этот подход нельзя применять, поскольку я не мог найти способ применить внешнее соединение, используя дополнительные. У модели переопределения может не быть строки, соответствующей каждой строке модели. Указание таблицы переопределения в предложении
tables
выполняет операцию с перекрестным продуктом, которая в сочетании с тем, где может использоваться для выполнения внутреннего соединения, а не для внешнего соединения (хотя я был бы счастлив, если бы ошибался).EDIT: Я понял, что select_related может быть в состоянии решить данную проблему, но если я фильтровать QuerySet порожденного
Model.objects.select_related('overridemodel').defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...)
на полеf1
, скажуqs.filter(f1='Random stuff')
, где положение для запроса фильтра используетModel.f1
поле, а не полеf1
сгенерировано в дополнительном. Таким образом, этот подход также бесполезен.Использование
Model.objects.raw()
для получения необработанного запроса.Это не стартер, потому что Django ORM становится бесполезным после использования
raw
, и мне нужно иметь возможность фильтровать/сортировать объекты модели как часть приложения.Определение методов/свойств на классе
Model
.Опять же, я не буду использовать те же названия полей, которые включают в себя охоту через код для всех применений и внесение изменений.
Создание представления в базе данных, которое дает мне то, что я хочу, и создание неуправляемой модели, которая считывает данные с этого вида.
Это, вероятно, лучшее решение для моей проблемы, но прежде не использовавшее ранее неуправляемую модель, я не знаю, как это сделать или какие проблемы я могу встретить. Одна из проблем, которые я могу придумать из головы, заключается в том, что мое мнение всегда должно быть синхронизировано с моделями, но это кажется небольшой ценой для оплаты по сравнению с охотой через кодовую базу и внесением изменений, а затем тестированием, чтобы увидеть, все сломалось.
Итак, у вас оно есть. Как всегда, любая помощь/указатели будут с благодарностью оценены. Я попытался представить как можно более минимальный пример; поэтому, если потребуется больше информации, я буду рад предоставить ее.
Кроме того, я использую Django 1.8 с MySQL.