Reputation: 1257
I'm improving the standart poll app.
There I have some code that needs to be repeated in many views: code that counts number of various polls (active, inactive, popular) for posting the number in the links, such as:
1) View all active polls (number of polls).
2) View all closed polls (number of polls).etc.
So matter of fact that I need repeat this code many times, I decided to make a decorator:
def count_number_of_various_polls(func):
def count():
# Count the number of active polls.
all_active_polls = Poll.active.all()
num_of_active_polls = len(all_active_polls)
# Count the number of inactive polls.
all_inactive_polls = Poll.inactive.all()
num_of_inactive_polls = len(all_inactive_polls)
# Count the number of popular polls per the last month.
popular_polls = Poll.popular.filter(pub_date__gte=timezone.now()
- datetime.timedelta(days=days_in_curr_month))
num_of_popular_polls = len(popular_polls)
func()
return count
Then I want to decorate my index
view:
@count_number_of_various_polls
def index(request):
latest_poll_list = Poll.active.all()[:5]
return render(request, 'polls/index.html', {
'latest_poll_list': latest_poll_list,
'num_of_popular_polls': num_of_popular_polls,
'num_of_active_polls': num_of_active_polls,
'num_of_inactive_polls': num_of_inactive_polls
})
And when I try to open the polls index page on my dev server I get the following error:
TypeError at /polls/
count() takes no arguments (1 given)
I have no idea what the 1 argument is. Where is the problem?
Upvotes: 0
Views: 46
Reputation: 599610
The argument is the argument to the view, ie request
. You need to accept that argument in your count()
function, and pass it onto func
:
def count_number_of_various_polls(func):
def count(request):
...
func(request)
return count
However this isn't really a very good way of doing this, since you're still relying on the view itself to pass the elements into the template context. You should look into context processors and template tags as better alternatives.
Upvotes: 4