Django-如何将元素从一个视图复制到另一个视图?

时间:2016-11-29 17:25:35

标签: python 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中显示的信息添加到第二个veiw,方法是将第一个view的代码附加到其中,即添加:

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显示“标签视图”页面元素,我想要做的是将report-ccis(...)视图显示的标签中的内容复制到report-overview(...) view, also keeping all of the information currently displayed by the报告显示的标签中-overview(...)`查看那里。

修改

啊,实际上,我刚刚发现尽管两个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 %}

else视图中if的{​​{1}}语句包含以下行:

report_overview(...)

我猜是当选择该标签时,HTML文件的“标签”视图部分在哪里/如何更改??

如何将此内容添加到HTML中context['html'] = render_to_string('costing/report_ccis.html', context) 块的report-overview标签中?:

tabs

修改

我刚刚发现HTML页面上的'标签'报告区域有一个视图,它定义为:

{% 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 %}

似乎这个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 个答案:

答案 0 :(得分:1)

您描述的问题 - 重复的代码 - 是重构解决的许多常见问题之一。要在此处应用的重构操作称为Extract Method

对于共享代码,将公共代码提取到单独的函数,并从需要它的所有不同位置调用该函数。

对于共享模板内容,将公共内容提取到单独的模板文件中,并从需要它的所有不同位置{% include … %}该模板。