Reputation: 3880
Hello i'm a newbie to Django, i'm currently having problem figure out how to redirect and return value
I have a url with 2 parameters that are month and year . After clicking on it , it should redirect to page with url like so "list-working-sessions/year/month" with year and month parameters base on the action.
urls.py
url(r'^list-working-sessions/(?P<year>\w+?)/(?P<month>\w+?)/$',
views.list_working_sessions,
name='list_working_sessions')
base.html
<ul class="treeview-menu">
<li id="list-daily-task">
<a href="{% url 'list_working_sessions' %}">
<i class="fa fa-circle-o"></i>List Working Session</a>
</li>
</ul>
The page have a table and a form to search by month and year:
list_working_sessions.html
<div class="box">
<div class="box-header">
<center>
<h3 class="box-title">List Working Sessions</h3>
</center>
</div>
<!-- /.box-header -->
<div class="box-body">
<form class="form-horizontal" action="/list-working-sessions" method="GET">
{% csrf_token %}
<div class="table-responsive">
<table class="table table-borderless" id="dynamic_field">
<tr>
<th style="width:20%; border-top:none">Month</th>
<th style="width:20%; border-top:none">Year</th>
<th style="width:20%; border-top:none"></th>
<th style="border-top:none"></th>
</tr>
<tr>
<td style="border-top:none">
<select name="month" class="form-control" id="month" required>
<option value="1" selected>1</option>
<option value="2" selected>2</option>
<option value="3" selected>3</option>
<option value="4" selected>4</option>
<option value="5" selected>5</option>
<option value="6" selected>6</option>
<option value="7" selected>7</option>
<option value="8" selected>8</option>
<option value="9" selected>9</option>
<option value="10" selected>10</option>
<option value="11" selected>11</option>
<option value="12" selected>12</option>
</select>
</td>
<td style="border-top:none">
<select name="year" class="form-control" id="year" required>
<option value="2019" selected>2019</option>
<option value="2020" selected>2020</option>
</select>
</td>
<td style="border-top:none"><button type="submit" id="submit" class="btn btn-info">Send</button></td>
</tr>
</table>
</div>
</form>
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Date</th>
<th>Working Sessions</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
{% for lws in working_session_list|dictsortreversed:"date"%}
<tr>
<td>{{lws.date}}</td>
<td>
<ul class="list-group">
{% for lgbd in lws.list_group_by_date %}
<ul>
{% for item in lgbd.items %}
<li>{{item.start.time}} - {{item.end.time|default:"Not ended yet" }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
</td>
<td>
{{lws.sum_duration}} minutes
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!-- /.box-body -->
</div>
If the link is clicked from base.html then it will return list_working_sessions.html page with table value(working session objects) from the current month and year and the url have current month and year parameter. If the link is the GET request from the form then it will return the page with table values from the search month and year and the url also include that parameter
I wrote the following view so it handle all in 1 function but i'm having problem figure out how to redirect and return values from the function and also changing url parameter. I'm used to doing POST form request but never do redirect with GET form request before
views.py:
def list_working_sessions(request):
flag_date = []
working_session_list = []
if request.method == 'GET':
month = int(request.GET.get('month'))
year = int(request.GET.get('year'))
daily_working_sessions = WorkingSession.objects.filter(device__employee_id=request.user,start__month=month,start__year=year).order_by('-start')
else:
month = datetime.today().month
year = datetime.today().year
daily_working_sessions = WorkingSession.objects.filter(device__employee_id=request.user).order_by('-start')
for item in daily_working_sessions:
if item.start.date() not in flag_date:
flag_date.append(item.start.date())
list_group_by_date = []
group_by_date = daily_working_sessions.filter(start__date=item.start.date())
list_group_by_date.append({
"items": group_by_date
})
sum_duration = 0
for item in group_by_date:
sum_duration += item.get_duration
working_session_list.append({
"date": str(item.start.date()),
"list_group_by_date": list_group_by_date,
"sum_duration": sum_duration
})
num_days = calendar.monthrange(year, month)[1]
days = [date(year, month, day) for day in range(1, num_days+1)]
for day in days:
if day not in flag_date:
working_session_list.append({
"date": day.strftime('%Y-%m-%d'),
"list_group_by_date": '',
"sum_duration": '0'
})
return render(request, 'pages/list_working_sessions.html', {
'working_session_list': working_session_list,
'state': 'list-working-sessions'
})
url = reverse('list_working_sessions', kwargs={'year': year, 'month': month})
return HttpResponseRedirect(url)
EDIT: i changed base.html to
{% now "Y" as YEAR %}
{% now "m" as MONTH %}
<a href="{% url 'list_working_sessions' year=YEAR month=MONTH %}">
and the error gone but when i click on the url from base.html got this
TypeError at /list-working-sessions/2019/07/ list_working_sessions() got an unexpected keyword argument 'year'
EDIT 2: i changed my view function to :
def list_working_sessions(request, month, year):
flag_date = []
working_session_list = []
month = int(month)
year = int(year)
daily_working_sessions = WorkingSession.objects.filter(device__employee_id=request.user,start__month=month,start__year=year).order_by('-start')
and the URL from base.html return the right redirect URL '/list-working-sessions/2019/7/' and value in table but when i search with the form the URL is different
Page not found (404)
Request Method: GET
Request URL: http://localhost:8888/list_working_sessions_get?month=8&year=2019
can't seem to get month and year from this URL to my view function
Upvotes: 1
Views: 1086
Reputation: 51938
You need to update the view to pass year and month arguments:
def list_working_sessions(request, year, month):
flag_date = []
working_session_list = []
if request.method == 'GET':
# removed request.GET.get(...) because year and month arguments coming direct in from url and view arguments
daily_working_sessions = WorkingSession.objects.filter(device__employee_id=request.user,start__month=month,start__year=year).order_by('-start')
else:
month = datetime.today().month
year = datetime.today().year
Update I think you can try like this:
# url
url(r'^list-working-sessions/',
views.list_working_sessions,
name='list_working_sessions')
# view(same as your question)
def list_working_sessions(request):
flag_date = []
working_session_list = []
if request.method == 'GET':
month = int(request.GET.get('month'))
year = int(request.GET.get('year'))
# rest of the code
url = '{}?year={}&month={}'.format(reverse('list_working_sessions'), year, month)
# template:
{% now "Y" as YEAR %}
{% now "m" as MONTH %}
<a href="{% url 'list_working_sessions' %}?year={{ YEAR }}&month={{ MONTH }}">
Update2 I think you can try like this:
# url
url(r'^list-working-sessions/',
views.list_working_sessions,
name='list_working_sessions'),
url(r'^list-working-sessions/(?P<year>\w+?)/(?P<month>\w+?)/$',
views.list_working_sessions,
name='list_working_sessions_updated')
# view
def list_working_sessions(request, year=None, month=None):
flag_date = []
working_session_list = []
redirect = False
if request.method == 'GET':
if not month:
month = int(request.GET.get('month'))
redirect = True
if not year:
year = int(request.GET.get('year'))
redirect = True
# other codes
if not redirect:
return render(...)
else:
url = reverse('list_working_sessions_updated', kwargs={'year': year, 'month': month})
return HttpResponseRedirect(url)
# template:
{% now "Y" as YEAR %}
{% now "m" as MONTH %}
<a href="{% url 'list_working_sessions_updated' year=YEAR month=MONTH %}">
Upvotes: 2