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)
1 Answer 1
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)
-
\$\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 asif location:. I'll leave the question open for now and see what other suggestions may be offered. \$\endgroup\$Dodge– Dodge2019年05月01日 12:47:28 +00:00Commented May 1, 2019 at 12:47