Amistad
Amistad

Reputation: 7410

Reuse code from a Django view into another view

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

Answers (2)

zEro
zEro

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

Muhammad Tahir
Muhammad Tahir

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

Related Questions