Как я могу скопировать все определения полей из одного класса модели в другой? - PullRequest
0 голосов
/ 10 мая 2011

У меня есть модель ( Patch ), в которой есть поле автора, и мне нужно сгенерировать несколько отчетов, всегда отфильтровывая строки, автор которых не содержит строку '@ example.com'.Учитывая, что Patch определен в отдельном приложении django, которое я не хочу менять, моя идея заключалась в создании представления БД (скажем, ExampleComPatch , доступ к которому осуществляется с помощью класса неуправляемой модели), которое фильтруетвычеркните все строки, которые мне не интересны, а затем поместите методы отчетности в этот новый класс модели.

Чтобы избежать дублирования кода, я сделал свой новый класс модели наследуемым от Patch.Это прекрасно работает только с несколькими оговорками:

  1. В моем представлении должны быть определены все столбцы в Patch, а также дополнительный 'patch_ptr_id', так как django считает, что я хочу реального наследования в БД
  2. Поскольку это неуправляемый класс модели, тесты, использующие это представление, должны создавать его вручную

Однако, поскольку django считает, что я хочу реального наследования, всякий раз, когда я удаляю экземплярPatch, в конечном итоге он проходит через все свои подобъекты (например, строки в ExampleComPatch, которые ссылаются на него), что означает, что тестам, которые не имеют никакого отношения к ExampleComPatch, теперь может понадобиться создать представление БД вручную, если им нужно удалить ()строка из таблицы исправлений.

Я думаю, что наследование может быть не лучшим вариантом здесь, но я бы очень хотел избежать дублирования кода, поэтому мне интересно, есть ли способ скопировать все поляопределения из Patch в ExampleComPatch.Или, может быть, даже совершенно другой подход, который позволил бы мне использовать представление БД (чтобы уменьшить сложность моих методов отчетности) с методами отчетности, определенными вне Patch, поскольку они не имеют особого смысла.

Ответы [ 3 ]

1 голос
/ 11 мая 2011

Модели с прокси - ваш билет.Примерно так:

from somewhere import Patch

class FilteredPatchManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        return super(FilteredPatchManager, self).get_query_set().exclude(author__contains='@example.com')


class FilteredPatch(Patch)
    objects = FilteredPatchManager()

    class Meta:
        proxy = True

Затем используйте FilteredPatch.objects для запросов вместо Patch.objects.

0 голосов
/ 10 мая 2011

Зачем вам вообще нужно наследовать или копировать код?Вы можете импортировать модель в ваше текущее приложение и при необходимости фильтровать - если хотите, вы можете создать в своем приложении функцию, которая обернет фильтр, поэтому вы просто вызываете эту функцию, чтобы вернуть отфильтрованные экземпляры.

0 голосов
/ 10 мая 2011

Я думаю, вы делаете вещи намного более сложными, чем они должны быть. Если я правильно понимаю, вы хотите исключить определенные объекты из некоторых стандартных запросов get - если это так, вы должны изучить

Изменение исходного менеджера QuerySets

По сути, вы можете настроить то, что возвращает запрос, например:

# First, define the Manager subclass.
class PatchManger(models.Manager):
    def get_query_set(self):
        return super(PatchManager, self).get_query_set().exclude(author__contains='@example.com')

# Then hook it into the Patch model explicitly.
class Patch(models.Model):
    author = models.CharField(max_length=100)

    objects = PatchManager() # The custom manager.

Надеюсь, я правильно понял вашу проблему ...

Приветствия

Martin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...