You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何通过单个URL调用两个基于函数的视图?

解决Django同一URL下展示两个视图图表的问题

我懂你现在的困扰——你想在home/dashboard/这个页面同时展示两个图表,但目前两个视图函数各自生成一个图表的数据,没法在同一个URL里同时生效。核心问题其实是Django的URL规则里,同一个路径只能映射到一个视图,你之前重复设置URL的话,Django只会匹配第一个,第二个视图根本不会被触发。下面给你两种简单可行的解决办法:

方法1:合并两个视图函数的逻辑

最直接的方式就是把两个视图里生成图表的逻辑整合到一个函数中,一次性把两个图表的数据都传给模板。这样同一个URL只需要映射到这个合并后的视图即可。

修改后的视图函数代码:

from django.shortcuts import render
from django.db.models import Count, Q
import json
from .models import Department, Profile

def dashboard_view(request, *args, **kwargs):
    # 处理部门容器统计图表(原get_dept逻辑)
    dept_dataset = Department.objects.all() \
        .values('department') \
        .annotate(
            IT_count=Count('department', filter=Q(department="IT")),
            Sales_count=Count('department', filter=Q(department="Sales")),
            Admin_count=Count('department', filter=Q(department="Admin")),
            HR_count=Count('department', filter=Q(department="HR"))
        ) \
        .order_by('department')
    
    categories = []
    IT_series_data = []
    Sales_series_data = []
    Admin_series_data = []
    HR_series_data = []
    for entry in dept_dataset:
        categories.append(f'{entry["department"]} Department')
        IT_series_data.append(entry['IT_count'])
        Sales_series_data.append(entry['Sales_count'])
        Admin_series_data.append(entry['Admin_count'])
        HR_series_data.append(entry['HR_count'])
    
    chart2 = {
        'chart': {
            'type': 'column',
            'backgroundColor': '#E3F0E6',
            'option3d': {
                'enabled': "true",
                'alpha': 10,
                'beta': 15,
                'depth': 50,
            }
        },
        'title': {'text': 'Containers per department'},
        'xAxis': {'categories': categories},
        'yAxis': {
            'title': {'text': 'No.of containers'},
            'tickInterval': 1
        },
        'plotOptions': {
            'column': {
                'pointPadding': 0.2,
                'borderWidth': 0,
                'depth': 60,
            }
        },
        'series': [
            {'name': 'IT', 'data': IT_series_data, 'color': 'green'},
            {'name': 'Sales', 'data': Sales_series_data, 'color': 'yellow'},
            {'name': 'Admin', 'data': Admin_series_data, 'color': 'red'},
            {'name': 'HR', 'data': HR_series_data, 'color': 'blue'}
        ],
        'colorByPoint': "true",
    }
    dump2 = json.dumps(chart2)

    # 处理用户活跃状态统计图表(原get_profile逻辑)
    profile_dataset = Profile.objects \
        .values('is_active') \
        .annotate(
            is_active_count=Count('is_active', filter=Q(is_active=True)),
            not_is_active_count=Count('is_active', filter=Q(is_active=False))
        )
    
    is_active_series_data = []
    not_is_active_series_data = []
    for entry in profile_dataset:
        is_active_series_data.append(entry['is_active_count'])
        not_is_active_series_data.append(entry['not_is_active_count'])
    
    chart = {
        'chart': {
            'type': 'column',
            'backgroundColor': '#E3F0E6',
            'options3d': {
                'enabled': "true",
                'alpha': 10,
                'beta': 15,
                'depth': 50,
            }
        },
        'title': {'text': 'Active user on Current Platform'},
        'xAxis': {'categories': ['Active', 'Inactive']},
        'yAxis': {
            'title': {'text': 'No.of users'},
            'tickInterval': 1
        },
        'plotOptions': {
            'column': {
                'pointPadding': 0.2,
                'borderWidth': 0,
                'depth': 60,
            }
        },
        'series': [
            {'name': 'Active user', 'data': is_active_series_data, 'color': '#23CE3F'},
            {'name': 'Inactive user', 'data': not_is_active_series_data, 'color': '#FB3A3A'}
        ]
    }
    dump = json.dumps(chart)

    # 同时传递两个图表数据到模板
    return render(request, 'accounts/dashboard.html', {'chart': dump, 'chart2': dump2})

然后修改URL配置,只保留一条映射:

path('home/dashboard/', views.dashboard_view, name='dashboard'),

方法2:使用基于类的视图(CBV)拆分逻辑

如果想保持代码的模块化,也可以用CBV把两个图表的数据获取逻辑拆分成独立方法,再在get_context_data里统一传递给模板:

from django.views.generic import TemplateView
from django.db.models import Count, Q
import json
from .models import Department, Profile

class DashboardView(TemplateView):
    template_name = 'accounts/dashboard.html'

    def _get_dept_chart_data(self):
        # 封装部门图表数据逻辑
        dept_dataset = Department.objects.all() \
            .values('department') \
            .annotate(
                IT_count=Count('department', filter=Q(department="IT")),
                Sales_count=Count('department', filter=Q(department="Sales")),
                Admin_count=Count('department', filter=Q(department="Admin")),
                HR_count=Count('department', filter=Q(department="HR"))
            ) \
            .order_by('department')
        
        categories = []
        IT_series_data = []
        Sales_series_data = []
        Admin_series_data = []
        HR_series_data = []
        for entry in dept_dataset:
            categories.append(f'{entry["department"]} Department')
            IT_series_data.append(entry['IT_count'])
            Sales_series_data.append(entry['Sales_count'])
            Admin_series_data.append(entry['Admin_count'])
            HR_series_data.append(entry['HR_count'])
        
        chart2 = {
            'chart': {
                'type': 'column',
                'backgroundColor': '#E3F0E6',
                'option3d': {
                    'enabled': "true",
                    'alpha': 10,
                    'beta': 15,
                    'depth': 50,
                }
            },
            'title': {'text': 'Containers per department'},
            'xAxis': {'categories': categories},
            'yAxis': {
                'title': {'text': 'No.of containers'},
                'tickInterval': 1
            },
            'plotOptions': {
                'column': {
                    'pointPadding': 0.2,
                    'borderWidth': 0,
                    'depth': 60,
                }
            },
            'series': [
                {'name': 'IT', 'data': IT_series_data, 'color': 'green'},
                {'name': 'Sales', 'data': Sales_series_data, 'color': 'yellow'},
                {'name': 'Admin', 'data': Admin_series_data, 'color': 'red'},
                {'name': 'HR', 'data': HR_series_data, 'color': 'blue'}
            ],
            'colorByPoint': "true",
        }
        return json.dumps(chart2)

    def _get_profile_chart_data(self):
        # 封装用户活跃图表数据逻辑
        profile_dataset = Profile.objects \
            .values('is_active') \
            .annotate(
                is_active_count=Count('is_active', filter=Q(is_active=True)),
                not_is_active_count=Count('is_active', filter=Q(is_active=False))
            )
        
        is_active_series_data = []
        not_is_active_series_data = []
        for entry in profile_dataset:
            is_active_series_data.append(entry['is_active_count'])
            not_is_active_series_data.append(entry['not_is_active_count'])
        
        chart = {
            'chart': {
                'type': 'column',
                'backgroundColor': '#E3F0E6',
                'options3d': {
                    'enabled': "true",
                    'alpha': 10,
                    'beta': 15,
                    'depth': 50,
                }
            },
            'title': {'text': 'Active user on Current Platform'},
            'xAxis': {'categories': ['Active', 'Inactive']},
            'yAxis': {
                'title': {'text': 'No.of users'},
                'tickInterval': 1
            },
            'plotOptions': {
                'column': {
                    'pointPadding': 0.2,
                    'borderWidth': 0,
                    'depth': 60,
                }
            },
            'series': [
                {'name': 'Active user', 'data': is_active_series_data, 'color': '#23CE3F'},
                {'name': 'Inactive user', 'data': not_is_active_series_data, 'color': '#FB3A3A'}
            ]
        }
        return json.dumps(chart)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['chart'] = self._get_profile_chart_data()
        context['chart2'] = self._get_dept_chart_data()
        return context

对应的URL配置:

path('home/dashboard/', views.DashboardView.as_view(), name='dashboard'),

最后记得在模板dashboard.html里,分别用{{ chart }}和{{ chart2 }}来初始化两个图表即可。

内容的提问来源于stack exchange,提问作者Django Newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:10:11