Reputation: 7410
So I have a Django(1.8.9) functional view as follow:
@api_view(['GET')]
def fruit_ranker(request):
"""
This view is responsible for generating the list of top 5
fruits based on sales
"""
****busines logic***
****busines logic***
****busines logic***
****busines logic***
....
....
This particular view is then tied to a URL in the urls.py such that http://127.0.0.1:8000/app_name/fruit-ranker gives me the JSON output for the top 5 fruits. Works as expected.
Now I have the requirement to do the same for the top 5 vegetables and it needs to have a separate URL like http://127.0.0.1:8000/app_name/veggie-ranker.So I create the following view to be tied to this URL, as follows:
@api_view(['GET')]
def vegetable_ranker(request):
"""
This view is responsible for generating the list of top 5
vegetables based on sales
"""
The issue is the business logic is exactly the same albeit for a select statement in the SQL where for the first case, I select the fruits and in the second case, I select vegetables.How can I reuse all the existing code in the first view without having to rewrite it again and also accommodating the small SQL change ? Can I somehow add the first view as a decorator to the second view so that I can abstract all the code and also allowing me the flexibility to make the SL change ?
Upvotes: 0
Views: 796
Reputation: 1263
If you create a generic ranker, such as this:
def generic_ranker(request, field_or_model_name):
"""
This function is responsible for generating the list of top 5
field_or_model based on sales
"""
***business logic***
***business logic***
***business logic***
***business logic***
Then your actual views will be:
@api_view(['GET')]
def vegetable_ranker(request):
"""
This view is responsible for generating the list of top 5
vegetables based on sales
"""
return generic_ranker(request, Vegetable)
@api_view(['GET')]
def fruit_ranker(request):
"""
This view is responsible for generating the list of top 5
vegetables based on sales
"""
return generic_ranker(request, Fruit)
However, I wonder why you rely on function views. If you quickly take a look at Class based views, you'll realize you can get so many things done so efficiently.
Upvotes: 1
Reputation: 5184
Although it is best to keep both the views separate (in case in future you want to change one but not other), yet if you want to use one view you can do.
def combined_view(request):
if request.path == 'app_name/veggie-ranker/':
# return top 5 vegitables
else:
# return top 5 fruites
or you can do:
# in urls.py
url(r'^/(?P<return_type>.+)/$')
# in views.py
def combined_view(request, return_type):
if return_type == 'veggie-ranker':
# return top 5 vegetables
elif return_type == 'fruit-ranker':
# return top 5 fruits
else:
raise Http404
Upvotes: 1