简体   繁体   中英

Django render and redirect URL

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

You need to update the view to pass year and month arguments:

def list_working_sessions(request, , ):
    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 %}">

年和月可能是数字值,因此请尝试以下

list-working-sessions/(?P[\w\d]+?)/(?P[\w\d]+?)/$

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM