Gunnit
Gunnit

Reputation: 1074

Django: How to optimize and reduce repetitive code the django way?

I am new to development and to Django, still learning OOP but I wanted to learn better with some examples from the code that I created. I have created a function in my view file. The function is getting very long and probably I will have to make it longer. I think the if statement could be written as a function but not sure where to start. What would be a way to reduce the code making it easier to maintain. Here is the code:

def processView(request, pk):
    
    process = ProcessInfo.objects.get(id=pk)

    #bottlenecks = get_object_or_404(ProcessBottlenecks, process_info_id=process.id) 
    try:
        details = ProcessDetails.objects.get(process_info_id=process.id)        
    except ProcessDetails.DoesNotExist:
        details = None

    try:
        score = ProcessScoring.objects.get(process_score_id=pk)
    except ProcessScoring.DoesNotExist:
        score = None
    
    try:
        assumptions = ProcessAssumptions.objects.get(process_rel_process=process.id)       
    except ProcessAssumptions.DoesNotExist:
        assumptions = None
    
       
    color_bottleneck = None
    color_quality = None
    color_datacomplexity = None
    color_technology = None
    color_transformation = None
    color_driversforchange = None
    color_technology = None


    #B
    if score.tot_score_bottlenecks_scoring in range(0, 200):
        color_bottleneck = 'badge-primary'   
    if score.tot_score_bottlenecks_scoring in range(100, 500):
        color_bottleneck = 'badge-danger'
    if score.tot_score_bottlenecks_scoring in range(500, 1000):
        color_bottleneck = 'badge-warning'    
    if score.tot_score_bottlenecks_scoring >= 1000:
        color_bottleneck = 'badge-success'
        #P
    if score.tot_score_dataquality in range(0, 200):
        color_quality = 'badge-primary'   
    elif score.tot_score_dataquality in range(200, 500):
        color_quality = 'badge-danger'
    elif score.tot_score_dataquality in range(500, 100):
        color_quality = 'badge-warning'    
    elif score.tot_score_dataquality >= 1000:
        color_quality = 'badge-success'
        #D
    if score.tot_score_datacomplexity in range(0, 200):
        color_datacomplexity = 'badge-primary'   
    if score.tot_score_datacomplexity in range(200, 500):
        color_datacomplexity = 'badge-danger'
    if score.tot_score_datacomplexity in range(500, 1000):
        color_datacomplexity = 'badge-warning'    
    if score.tot_score_datacomplexity >= 1000:
        color_datacomplexity = 'badge-success'
        #TECHNOLOGY
    if score.tot_score_technology in range(0, 200):
        color_technology = 'badge-primary'   
    if score.tot_score_technology in range(200, 500):
        color_technology = 'badge-danger'
    if score.tot_score_technology in range(500, 1000):
        color_technology = 'badge-warning'    
    if score.tot_score_technology >= 1000:
        color_technology = 'badge-success'
        #T
    if score.tot_score_transformation in range(0, 200):
        color_transformation = 'badge-primary'   
    if score.tot_score_transformation in range(200, 500):
        color_transformation = 'badge-danger'
    if score.tot_score_transformation in range(500, 1000):
        color_transformation = 'badge-warning'    
    if score.tot_score_transformation >= 1000:
        color_transformation = 'badge-success'
        #DRIVERSFORCHANGE
    if score.tot_score_driversforchange in range(0, 200):
        color_driversforchange = 'badge-primary'   
    if score.tot_score_driversforchange in range(200, 500):
        color_driversforchange = 'badge-danger'
    if score.tot_score_driversforchange in range(500, 1000):
        color_driversforchange = 'badge-warning'    
    if score.tot_score_driversforchange >= 1000:
        color_driversforchange = 'badge-success'
        #S
    if score.tot_score_scalability in range(0, 200):
        color_scalability = 'badge-primary'   
    if score.tot_score_scalability in range(200, 500):
        color_scalability = 'badge-danger'
    if score.tot_score_scalability in range(500, 1000):
        color_scalability = 'badge-warning'    
    if score.tot_score_scalability >= 1000:
        color_scalability = 'badge-success'


    context ={
    'process':process,
    'details':details,
    'score':score,
    'assumptions':assumptions, 
    'color_bottleneck' : color_bottleneck,
    'color_quality':color_quality,
    'color_datacomplexity':color_datacomplexity,
    'color_technology':color_technology,
    'color_transformation' : color_transformation,
    'color_driversforchange':color_driversforchange, 
    'color_scalability' : color_scalability
    }
    return render(request, 'process/process_view.html', context)

Here is another example from forms.py. Here I have the form fields repeating and is creating hundreds of lines

swivel= forms.CharField(
    label='Swivel Activities',
    required=False,
    help_text='Are swivel chair activities present?',
    widget=forms.Select(choices=CHECK))

process_objectives= forms.CharField(
    label='Clear Process Objectives',
    required=False,
    help_text='Are process outcomes objective and measurable?',
    widget=forms.Select(choices=CHECK))

stable_rules= forms.CharField(
    label='Stable Rules',
    required=False,
    help_text='Are the decision rules governing the process stable?',
    widget=forms.Select(choices=CHECK))

.....

Upvotes: 0

Views: 90

Answers (2)

Eduardo Vicentini
Eduardo Vicentini

Reputation: 56

You can factor out the if block as a function:

badge_selecting(attribute):
    if attribute in range(0, 200):
        color = 'badge-primary'   
    elif attribute in range(100, 500):
        color = 'badge-danger'
    elif attribute in range(500, 1000):
        color = 'badge-warning'    
    elif attribute >= 1000:
        color = 'badge-success'

    return color

And you call the function as:

color_bottleneck = badge_selection(score.tot_score_bottlenecks_scoring)

For every attribute.

The answer for the second problem is the same, so you can create a function such as:

def form_creation(label, help_text):
    form = forms.CharField(
    label=label,
    required=False,
    help_text=help_text,
    widget=forms.Select(choices=CHECK))

    return form

If you need a variation for the other fields, but yet these are the attributes you want to use in most cases, you can use default argument values and create the function like this one:

def form_creation(label, help_text, required=False, widget=forms.Select(choices=CHECK)):

So you don´t need to put these values to all the forms, just the ones that change they.

Upvotes: 2

hansTheFranz
hansTheFranz

Reputation: 2570

One way to minimise your code would be to write a function that you call to get the colors. It seemed that you are always checking for the same ranges and colors so just use a variable for the score and make a reusable function.

def get_color(score):
  if score in range(0, 200):
      color = 'badge-primary'   
  elif score in range(100, 500):
      color = 'badge-danger'
  elif score in range(500, 1000):
      color = 'badge-warning'    
  else:
      color = 'badge-success'
  return color

color_scalability = get_color(score.tot_score_scalability)
color_transformation = get_color(score.tot_score_transformation)
...

when you repeat yourself try to find a general approach. I hope that helps a little, if you have any questions please ask.

Upvotes: 1

Related Questions