2016-11-29 134 views
0

我有一個Django項目,並在其中一個頁面上顯示關於數據庫中某些信息的報告。Django如何將元素從一個視圖複製到另一個視圖?

我在其中顯示報告的元素有多個選項卡 - 每個選項卡都顯示關於數據庫中不同元素的「PDF樣式」報告。

我想將其中一個選項卡上顯示的信息添加到另一個選項卡,但我不太確定該如何執行此操作。

對於具有欲複製到其他標籤中的信息的標籤的視圖被定義與:

def report_ccis(request, project_id): 
    """ CCI items styled for pdf """ 
    project = Project.objects.get(id=project_id) 
    budget = get_current_budget(project_id) 

    cci_total_exc = budget.cci_total_exc_vat_final 
    cci_grouped_items = budget.cci_items.all().order_by('project_room', 'name') 

    context = { 
     'project': project, 
     'cci_total_exc': cci_total_exc, 
     'cci_grouped_items': cci_grouped_items, 
     'webview': 1, 
    } 

    try: context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs 
    except ObjectDoesNotExist: pass 

    if request.GET.get('stage') == 'pd': 
     """ Render post deposit homepage """ 
     context['html'] = render_to_string('costing/report2_ccis.html', context) 
     context['active_tab'] = '4' 
     return render(request, 'costing/reports_post_deposit.html', context) 
    else: 
     """ Render pre deposit homepage """ 
     context['html'] = render_to_string('costing/report_ccis.html', context) 
     context['active_tab'] = '5' 
     return render(request, 'costing/reports_pre_deposit.html', context) 

和用於在其上欲顯示此信息的標籤的視圖被定義與:

def report_overview(request, project_id): 
    """ Budget overview styled for pdf """ 
    project = Project.objects.get(id=project_id) 

    budget = get_current_budget(project_id) 
    if not budget and not project.budget_versions.filter(current_marker=1): 
     Budget.objects.create(project=project, current_marker=1) 

    cci_total_exc = budget.cci_total_exc_vat 
    item_total_exc = budget.item_total_exc_vat() 
    total_exc = cci_total_exc + item_total_exc 
    total_exc_2 = budget.grand_total_exc_vat 
    total_inc = budget.grand_total_inc_vat 
    #----- Add CCIs to the 'Overview tab' ----- 
    cci_total_exc_final = budget.cci_total_exc_vat_final # ERF(29/11/2016 @ 1615) Changed from cci_total_exc to cci_total_exc_final 
    cci_grouped_items = budget.cci_items.all().order_by('project_room', 'name') 
    #-----(29/11/2016 @ 1615) ----- 

    context = { 
     'project': project, 
     'budget': budget, 
     'cci_total_exc': cci_total_exc, 
     'item_total_exc': item_total_exc, 
     'total_exc': total_exc, 
     'total_exc_2': total_exc_2, 
     'total_inc': total_inc, 
     #-----(29/11/2016 @ 1615) Add CCIs to the 'Overview tab'----- 
     'cci_grouped_items': cci_grouped_items, 
     'webview': 1, 
     #-----(29/11/2016 @ 1615) ----- 
    } 
    print '****************************************************' 
    try: 
     context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs/pages 
     print 'OPTION NAME', project.budget_versions.get(current_marker=1) 
    except ObjectDoesNotExist: 
     print 'No option found with current marker' 
     pass 

    if request.GET.get('pdf'): 
     template = get_template('costing/report_overview.html') 
     html = template.render(context) 

     file = open('test.pdf', "w+b") 
     pisaStatus = pisa.CreatePDF(html.encode('utf-8'), link_callback=fetch_resources, dest=file, 
      encoding='utf-8') 

     file.seek(0) 
     pdf = file.read() 
     file.close()    
     return HttpResponse(pdf, 'application/pdf') 

    else: 
     context['webview'] = 1 
     context['html'] = render_to_string('costing/report_overview.html', context) 
     context['active_tab'] = '1' 
     return render(request, 'costing/reports_pre_deposit.html', context) 

我試圖通過從第一到view其附加的代碼,即添加到添加在所述第一view到第二veiw顯示的信息:

if request.GET.get('pdf'): 
    """ Render post deposit homepage """ 
    context['html'] = render_to_string('costing/report2_ccis.html', context) 
    context['active_tab'] = '1' 
    return render(request, 'costing/reports_post_deposit.html', context) 
else: 
    """ Render pre deposit homepage """ 
    context['html'] = render_to_string('costing/report_ccis.html', context) 
    context['active_tab'] = '1' 
    return render(request, 'costing/reports_pre_deposit.html', context) 

report_overview視圖的結束,但是,當我顯示在瀏覽器頁面,並選擇在報告中的「概述」選項卡,我還只是看看發生了什麼顯示在─沒有的信息我已經從report_ccis視圖中複製顯示。

這是爲什麼?如何將一個view顯示的信息複製到另一個?

編輯

由於兩個report_ccis(...) &的report_overview(...)視圖返回相同的模板,該文件的HTML是:

{% extends "costing/reports_tabbed.html" %} 
{% load staticfiles utilities %} 

{% block title2 %} 
    | Pre-deposit reports 
{% endblock title2 %} 

{% block page_title %} 
    <a id="topbar-shortcuts" data-view-url="{% url 'hub:open_sidebar' %}?app={{app.name}}&p={{project.id}}&po=1"> 
     <span class="m-l-md">Reports</span> <img class="icon open text-sm m-l-md" src="{% static 'img/down-lt.png' %}" > 
    </a> 
    <div id="topbar-results" class="{{app.color}}" style="display:none;"></div> 
{% endblock page_title %} 


{% block tabs %} 
    {% with 'Overview, Construction budget, Schedule of works, Client choice items'|listify as tabs %} 
     {% for tab_name in tabs %} 
      {% with forloop.counter as tab %} 
       {% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a> 
      {% endwith %} 
     {% endfor %} 
    {% endwith %} 
{% endblock tabs %} 

這個HTML是顯示 'tabbed-視圖' 頁面元素,我想要做的是將report-ccis(...)視圖顯示的選項卡中的內容複製到report-overview(...) view, also keeping all of the information currently displayed by the報告概覽(...)視圖顯示的選項卡中。

編輯

啊,其實,我只是發現,雖然這兩種views返回相同的模板,還有一個report_ccis.html文件在我的項目結構,它具有以下代碼:

{% extends "pdf_base.html" %} 
{% load money_handling %} 

{% block content_overview %} 
{% endblock content_overview %} 
{% block content_construction %} 
{% endblock content_construction %} 
{% block content_schedule_of_works %} 
{% endblock content_schedule_of_works %} 
{% block content_report_by_class %} 
{% endblock content_report_by_class %} 
{% block content_ccis %} 
    {{block.super}} 
{% endblock content_ccis %} 

,並在report_overview(...)鑑於ifelse語句行:

context['html'] = render_to_string('costing/report_ccis.html', context) 

其中我猜是哪裏/如何選擇該選項卡時,這個「標籤」視圖HTML文件的一部分將被更改...?

如何將此內容添加到HTML中tabs塊的report-overview選項卡?:

{% block tabs %} 
    {% with 'Overview, Construction budget, Schedule of works, Client choice items'|listify as tabs %} 
     {% for tab_name in tabs %} 
      {% with forloop.counter as tab %} 
       {% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a> 
      {% endwith %} 
     {% endfor %} 
    {% endwith %} 
{% endblock tabs %} 

編輯

我剛剛發現,有是在HTML頁面上的「標籤」報告面積來看,它與定義:

def report_tabbed(request, project_id): 
    project = Project.objects.get(id=project_id) 
    tab = request.GET.get('tab', '1') 

    tab_map = { 
     '1': reverse('costing:report_overview', args=[project.id]), 
     '2': reverse('costing:report_construction', args=[project.id]), 
     '3': reverse('costing:budget', args=[project.budget_overview.version.pk])+"?report=1", 
    # '4': reverse('costing:report_by_class', args=[project.id]), 
     '4': reverse('costing:report_ccis', args=[project.pk]), 
    } 
    return HttpResponseRedirect(tab_map[tab]) 

看來,這view是什麼用來切換顯示在頁面的「標籤」區域中的報告。有沒有辦法將'4':reverse('costing:report_ccis', args=[project.pk]),合併到'1':reverse('costing:report_overview', args=[project.id]),

+0

我想你也只能修改你的模板。此外,如果您發佈有關視圖中未顯示的內容的問題,相關的模板代碼可能有助於回答。 – Ivan

+0

我在模板代碼中添加了兩個視圖所引用的模板。 – someone2088

回答

1

您描述的問題 - 重複代碼 - 是重構解決的許多常見問題之一。此處應用的重構操作稱爲Extract Method

對於共享代碼,將通用代碼提取到單獨的函數中,並從需要它的所有不同位置調用該函數。

對於共享模板內容,請將常用內容提取到單獨的模板文件,並從需要它的所有不同位置提取模板。

+0

'通用'代碼目前並不常見 - 我有兩個單獨的視圖(不同的代碼),每個視圖在同一個HTML模板上填充「選項卡式」顯示區域。兩個視圖都返回相同的模板(同一個HTML文件),但每個視圖都顯示「選項卡式」顯示區域的不同選項卡。在瀏覽器中顯示的第一個視圖的URL是:https://www.mysite.co.uk/costing/6172/report/ccis/, – someone2088

+0

,第二個視圖的瀏覽器中顯示的URL是:' https://開頭www.mysite.co.uk /成本/ 6172 /報告/概述/'。但是我可以通過選擇頁面的「標籤內容」區域中的每個標籤來切換瀏覽器中的'views',即整個頁面不重新加載/刷新/只有'標籤內容'區域改變,甚至儘管在選擇不同的選項卡時瀏覽器中的URL會發生變化。 – someone2088

相關問題