Как переопределить внутренний запрос на чтение класса или метода в django

Я хочу переопределить внутренний запрос на чтение, присутствующий в моем классе или методе. Я хочу написать обобщенное решение, чтобы оно работало на классе или методе, где я хочу изменить запросы на чтение.

Я пытаюсь использовать декораторы, промежуточное ПО и метаклассы, но мне не удается получить доступ к внутреннему запросу на чтение функции.

Я просто хочу изменить его, чтобы он брал его из реплики чтения. но я не могу сделать это для всех запросов чтения. Я могу модифицировать запрос на чтение так, чтобы он брался из реплики чтения только для нескольких классов или методов.

master_models.CarTransmission.objects.filter( # pylint: disable=E1101 variant_id__in=self.variant_ids ).values_list(*self.specifications, named=True) изменить это на-

master_models.CarTransmission.objects.using('replica').filter( # pylint: disable=E1101 variant_id__in=self.variant_ids ).values_list(*self.specifications, named=True)

оригинальный. model = get_object_or_404(master_models.Model,slug=slug)

измените это на - model = get_object_or_404(master_models.Model.objects.using('replica'),slug=slug)

Логика, которую я ожидаю, должна быть специфична для класса и метода. Если я применю это к классу, то все присутствующие методы должны изменить все внутренние запросы на чтение. Возможно ли это, или я должен перейти ко всем запросам и написать .using('replica')

pleaser не предоставляйте решения, которые работают для какого-то конкретного приложения, например, использование маршрутизации для перемещения его на перенаправление в реплику, так как они будут работать на всем проекте или на каком-то приложении, а не на конкретном методе или классе.

Для этого можно использовать маршрутизатор базы данных [Django-doc]:

# app_name/router.py


class ReplicateRouter:
    def db_for_read(self, model, **hints):
        return 'replicate'

для запросов, которые таким образом читаются из базы данных, вместо нее будет использоваться база данных replicate.

и установите маршрутизатор в настройках:

# settings.py

DATABASE_ROUTERS = ['app_name.router.ReplicateRouter']

Вы также можете добавить к этому больше контроля, например, только для определенных моделей с помощью:

# app_name/router.py


class ReplicateRouter:
    def db_for_read(self, model, **hints):
        if hasattr(model, 'use_replicate_for_read', False):
            return 'replicate'

и затем прикрепите атрибут user_replicate_for_read к модели, для которой вы хотите это сделать:

# app_name/models.py


class CarTransmission(models.Model):
    use_replicate_for_read = True
    # …
Вернуться на верх