Как выводить значения без написания логики в каждом представлении, Django?

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

views.py

def account(request):
    user_id = request.user.id
    balance = Customer.objects.filter(name_id=user_id).values("usd").first()
    bonus = Customer.objects.filter(name_id=user_id).values("bonus").first()

    context1 = {'usd':balance['usd'],
                'bonus':bonus['bonus'],

    return render(request, 'account.html', context1)

def main(request):
    (here I also need to request balance and bonus)

В def main(request): и на других страницах мне также нужен баланс и бонус, но я не очень хочу запрашивать эти значения в каждом представлении.
Могу ли я как-то написать это где-то один раз и вывести на страницах, и не писать это в каждом представлении?

Прежде всего, я не думаю, что выполнение запроса одной и той же модели Customer дважды для balance и для bonus более эффективно, чем запрос экземпляра Customer и доступ к его атрибутам как customer.balance/customer.bonus.

Тем не менее, есть два основных варианта сделать этот код многоразовым:

Поместите его в функцию

def get_balance_and_bonus(request):
    customer = Customer.objects.filter(name_id=request.user.id).first()
    return customer.balance, customer.bonus

И использовать его в представлении как:

balance, bonus = get_balance_and_bonus(request)

Второй (более сложный) метод - сделать декоратор для всех представлений, которые требуют клиента.

Декоратор выводит клиента:

def add_customer(func):
    def wrap(*args, **kwargs):
        request = args[0]
        user_id = request.user.id
        kwargs['customer'] = Customer.objects.filter(name_id=user_id).first()
        return func(*args, **kwargs)
    return wrap
    

Затем добавьте его во все функции, которым нужен клиент (Обратите внимание, что view в этом случае должен иметь соответствующий аргумент в нем)

@add_customer
def account(request, customer):

    context1 = {'usd': customer.balance,
                'bonus': customer. bonus,

    return render(request, 'account.html', context1)

@add_customer
def main(request, customer):
    # here customer.balance and customer.bonus are available
    
Вернуться на верх