Django CBV : create functions in the same class

Django CBV : create functions in the same class



I'm working on a new project based on Django Class Based View and I would like to get advices in order to factorize an important post function.


Django Class Based View


post function



I'm pretty new with this concept.



My post function looks like this :


def post(self, request, *args, **kwargs):
form = self.form_class()
query_document = None
query_document_updated = None
query_omcl = None
query_document_count = None


if "UpdateDocument" in request.POST:
checkbox_id = request.POST['DocumentChoice']
checkbox_id_minus_1 = int(checkbox_id) - 1

query_document_updated = Document.objects.get(id=checkbox_id)

OMCL_CODE = query_document_updated.omcl.code
SRC_FILENAME = query_document_updated.src_filename
FILENAME, file_extension = os.path.splitext(SRC_FILENAME)
CATEGORY = query_document_updated.category

if CATEGORY == "ANNUAL":
CATEGORY = "ANNUAL_REPORT"

# Get the new year selected by user
year = self.request.POST.get('q1year')

# Create the new document title updated by the new year
new_document_title = f"year_CATEGORY_OMCL_CODE" + " - " + f"SRC_FILENAME"

# Create the new document file updated by the new year
new_document_file = "omcl_docs/" + f"OMCL_CODE" + "/" +
f"year_CATEGORY_OMCL_CODE_checkbox_id_minus_1file_extension"

context =
'form': form,
'query_omcl' : query_omcl,
'query_document': query_document,
'query_document_updated': query_document_updated,
'query_document_count' : query_document_count

return render(request, self.template_name, context)



I would like to create two new functions : new_document_title and new_document_file and call both functions in post


new_document_title


new_document_file


post



How I can do that? Create both functions after post and pass variables in arguments ?





Is there any problem?
– JPG
Aug 20 at 10:20





@JerinPeterGeorge Not in my script, but I would like to know How I could rewrite my function post in order to cut it to different small functions
– Deadpool
Aug 20 at 10:25


post




3 Answers
3



I think you can do it in a number of ways! I'm writing a few of them here,


class methods


from rest_framework.views import APIView


class MyView(APIView):
def _new_document_title(self, *args, **kwargs):
# do something
return something

def _new_document_file(self, *args, **kwargs):
# do something
return something

def post(self, request, *args, **kwargs):
self._new_document_title() # calling "_new_document_title"
self._new_document_file() # _new_document_file
# do something
return some_response


Mixin class


class MyMixin(object):
def new_document_title(self, *args, **kwargs):
# do something
return something

def new_document_file(self, *args, **kwargs):
# do something
return something


class MyView(APIView, MyMixin):
def post(self, request, *args, **kwargs):
self.new_document_title() # calling "new_document_title"
self.new_document_file() # new_document_file
# do something
return some_response


from rest_framework.views import APIView


def new_document_title(self, *args, **kwargs):
# do something
return something


def new_document_file(self, *args, **kwargs):
# do something
return something


class MyView(APIView):

def post(self, request, *args, **kwargs):
new_document_title() # calling "new_document_title"
new_document_file() # new_document_file
# do something
return some_response



The code sample from @umair is the correct direction.



Still, if you want your code to be testable and maintainable at scale, you should outsource your helper functions into another python file:



helpers.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

class Helper():

@staticmethod
def utility_function_1(self, data):
return process(data)

@staticmethod
def utility_function_2(self, data):
return process(data)



views.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

# -- adjust -- >import helpers as helper

class CBV(APIView, Mixin):

def post(self, request, *args, **kwargs):
processed_data = helper.utility_function_1(request.data)
processed_data = helper.utility_function_2(processed_data)
return render(request, self.template_name, 'data': processed_data)





would you mind elaborating that If the utility_function_x function logic is not re-useable [maybe having some logic very specific to that view] then how will refactoring it to another Helper class help ?
– Umair
Aug 20 at 13:10


utility_function_x





No one said anything about not re-usable. By exporting it to another file you can more easily write unit tests for your helper-functions.
– Andrey Bulezyuk
Aug 21 at 5:37





:thumbsup: for test-ability
– Umair
Aug 21 at 5:49



You can write your function in the view class itself(if those are specific to that view) and also in some other mixin(when common to other views too).


#!/usr/bin/python
# -*- coding: utf-8 -*-


class Mixin(object):
def process(self, data):
return data


class CBV(APIView, Mixin):

def utility_function_1(self, data):
return self.process(data)

def utility_function_2(self, data):
return self.process(data)

def post(self, request, *args, **kwargs):
processed_data = self.utility_function_1(request.data)
processed_data = self.utility_function_2(processed_data)
return render(request, self.template_name, 'data': processed_data)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Help:Category

How can temperature be calculated given relative humidity and dew point?

I have a recursive function to validate tree graph and need a return condition