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