Home > other >  How to render the values without writing the logic in every view, Django?
How to render the values without writing the logic in every view, Django?

Time:11-06

In my view I want to request data from database, and on other page I also need this information, but I don't want to write this request logic again.

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)

In def main(request): and on other pages I also need balance and bonus, but I don't really want to request this values in every view.
Can I somehow write it somewhere once and to render on pages, and do not write it in every view??

CodePudding user response:

First of all, I don't think that doing query of the same Customer model twice for balance and for bonus is more efficient than query Customer instance and access its attributes as customer.balance/customer.bonus.

Nevertheless, there are two main options to make this code reusable:

Put it in the function

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

And use it in view as:

balance, bonus = get_balance_and_bonus(request)

Second (more sophisticated) method is to make a decorator for all views that require the customer.

Decorator to deduce customer:

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
    

Then add it to all functions that need customer (Note that view in this case must have the respective argument in it)

@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
    
  • Related