4
\$\begingroup\$

I'm a crop scientist and am currently building a web app that collects weather data then generates and displays modeled agriculturally relevant output. My question centers around an increasingly complex Django view and a desire to learn about a potentially superior implementation if one exists.

I have a Django view that allows the user to select a location from a Google maps layer when the page in initially rendered. Once a selection is made the view will check for location in URL request and render the template for an individual location. Once the individual location page is rendered the user has further options, like selecting a date range for desired data. The selection is made and submitted at which point the view will check for selectstartdate and selectenddate in the URL request and, if present, will render the single location view with data for the desired range. As I plan on adding several other interactive features, I'm beginning to realize that this view is going to get complicated quickly.

Is an intricate, conditionally driven Django view a reasonable implementation or is there a better way to do something like this?

Code

import time
from django.shortcuts import render
from locations.models import Location
from metload.models import Obsset
from datetime import datetime
from ETo_py.eto import EToEstimator

def single_location(**kwargs):

    """

    Process a bunch of weather parameters and return modeled output.
    This function is not a view, just a helper function for processing data.
    I have left out the lengthy inner workings of this function. 

    """

    return context


def index(request):

    print('hello')

    # Single location without date range selected.
    if 'location' in request.GET and \
            'selectstartdate' not in request.GET and \
            'selectenddate' not in request.GET:

        location = request.GET['location']
        selectstartdate = None
        selectenddate = None

        params = {
            'location': location,
            'selectstartdate': selectstartdate,
            'selectenddate': selectenddate,
        }

        context = single_location(**params)

        return render(request, 'locations/location.html', context)

    # Single location with a date range selected.
    elif 'location' in request.GET and  \
            'selectstartdate' in request.GET and \
            'selectenddate' in request.GET:

        location = request.GET['location']
        selectstartdate = request.GET['selectstartdate']
        selectenddate = request.GET['selectenddate']

        print(selectstartdate, selectenddate)

        params = {
            'location': location,
            'selectstartdate': selectstartdate,
            'selectenddate': selectenddate,
        }

        context = single_location(**params)

        return render(request, 'locations/location.html', context)

    # Initial page.
    else:
        # Get locations from db.
        locations = Location.objects.all()

        # Prepare locations dictionary for google map layer js.
        locs_ls = []
        for loc in locations:
            lat = loc.latitude
            lon = loc.longitude
            name = loc.name
            site_id = loc.site_id

            locs_ls.append({'site_id': site_id, 'name': name, 'lat': lat, 'lon': lon})

        context = {
            'locs_ls': locs_ls,
        }

        return render(request, 'locations/index.html', context)
\$\endgroup\$
2
\$\begingroup\$

Not sure this will solve all your problems, but you can give those GET parameters default values in case they don't exist. In my example below, they are given the default value of None. This should simplify things a bit.

def index(request):

    print('hello')


    location = request.GET.get('location', None)
    selectstartdate = request.GET.get('selectstartdate', None)
    selectenddate = request.GET.get('selectenddate', None)

    if location is not None or selectstartdate is not None and selectenddate is not None:

        # Get locations from db.
        locations = Location.objects.all()

        # Prepare locations dictionary for google map layer js.
        locs_ls = []
        for loc in locations:
            lat = loc.latitude
            lon = loc.longitude
            name = loc.name
            site_id = loc.site_id

            locs_ls.append({'site_id': site_id, 'name': name, 'lat': lat, 'lon': lon})

        context = {
            'locs_ls': locs_ls,
        }

        return render(request, 'locations/index.html', context)

    else:

        params = {
            'location': location,
            'selectstartdate': selectstartdate,
            'selectenddate': selectenddate,
        }

        context = single_location(**params)

        return render(request, 'locations/location.html', context)
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the feedback. I did not know that it was possible to assign default values to the GET parameters. This may be helpful. I do know that if location is not None: could also be written as if location:. I'll leave the question open for now and see what other suggestions may be offered. \$\endgroup\$ – Dodge May 1 '19 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.