我正在用两个主键(这是一个旧数据库)构建一个求和。
基本上我想做的是单击表格元素,然后基于模型上的主键重定向到另一页。
我找不到有关如何使用Django基于类的视图执行此操作的任何信息
这是我的代码:
models.py
class RmDadoscarteira(models.Model):
dtcalculo = models.DateField(db_column='dtCalculo', primary_key=True) # Field name made lowercase.
cdcarteira = models.CharField(db_column='cdCarteira', max_length=50) # Field name made lowercase.
nmcarteira = models.CharField(db_column='nmCarteira', max_length=255, blank=True, null=True) # Field name made lowercase.
pl = models.FloatField(db_column='PL', blank=True, null=True) # Field name made lowercase.
retornocota1d = models.FloatField(db_column='RetornoCota1d', blank=True, null=True) # Field name made lowercase.
var = models.FloatField(db_column='Var', blank=True, null=True) # Field name made lowercase.
var_lim = models.FloatField(db_column='VaR_Lim', blank=True, null=True) # Field name made lowercase.
var_variacao1d = models.FloatField(db_column='VaR_Variacao1d', blank=True, null=True) # Field name made lowercase.
var_variacao63d = models.FloatField(db_column='VaR_Variacao63d', blank=True, null=True) # Field name made lowercase.
var_consumolimite = models.FloatField(db_column='VaR_ConsumoLimite', blank=True, null=True) # Field name made lowercase.
stress = models.FloatField(db_column='Stress', blank=True, null=True) # Field name made lowercase.
stress_lim = models.FloatField(db_column='Stress_Lim', blank=True, null=True) # Field name made lowercase.
stress_variacao1d = models.FloatField(db_column='Stress_Variacao1d', blank=True, null=True) # Field name made lowercase.
stress_variacao63d = models.FloatField(db_column='Stress_Variacao63d', blank=True, null=True) # Field name made lowercase.
stress_consumolimite = models.FloatField(db_column='Stress_ConsumoLimite', blank=True, null=True) # Field name made lowercase.
grupo = models.CharField(db_column='Grupo', max_length=20, blank=True, null=True) # Field name made lowercase.
var_pl = models.FloatField(db_column='VaR_PL', blank=True, null=True) # Field name made lowercase.
stress_pl = models.FloatField(db_column='Stress_PL', blank=True, null=True) # Field name made lowercase.
objetos = models.Manager()
class Meta:
managed = False
db_table = 'RM_DadosCarteira'
unique_together = (('dtcalculo', 'cdcarteira'),)
views.py
from django.shortcuts import render, HttpResponse
from .models import *
import json
import pandas as pd
from django.views.generic.base import TemplateView
from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
# View do relatorio Flagship Solutions
#def FlagshipSolutions(request):
# render(request, 'dash_solutions_completo.html')
class VisualizaFundoSolutions(UpdateView):
template_name = "prototipo_fundo.html"
model = RmDadoscarteira
context_object_name = 'fundos_metricas'
fields = 'all'
success_url = reverse_lazy("portal_riscos:dash_solutions")
def FlagshipSolutions(request):
# Queryset Tabela Diaria
query_carteira = RmDadoscarteira.objetos.filter(grupo='Abertos')
# Data Mais recente
dt_recente = str(query_carteira.latest('dtcalculo').dtcalculo)
# Filtrando queryset para data mais recente
query_carteira = query_carteira.filter(dtcalculo=dt_recente)
# Preparando os dados para o grafico de utilizacao de var e stress
util_var = [round(obj['var_consumolimite'] * 100,2) for obj in query_carteira.values()]
util_stress = [round(obj['stress_consumolimite'] * 100,2) for obj in query_carteira.values()]
# Queryset Historico Graficos
### Definir um filtro de data
query_hist = RmHistoricometricas.objetos.filter(grupo='Abertos').filter(dtcalculo__gte='2018-07-11')
### Queryset temporario ate dados de retorno e var estarem iguais
query_data = RmHistoricometricas.objetos.filter(grupo='Abertos').filter(dtcalculo__gte='2018-07-11').filter(info='% VaR')
## Data Frames de Saida
# Data Frame Historico
df_hist = pd.DataFrame(list(query_hist.values()))
# Criando uma chave de concateno
df_hist['concat'] = df_hist['dtcalculo'].astype(str) + df_hist['cdcarteira']
df_hist['valor'] = round(df_hist['valor'] * 100, 2)
# Data Frame VaR PL Historico
df_hist_var = df_hist[df_hist['info']=='% VaR']
# Data Frame Stress PL Historico
df_hist_stress = df_hist[df_hist['info']=='% Stress']
# Data Frame Consumo VaR
df_hist_var_cons = df_hist[df_hist['info']=='% Utilização Limite VaR']
# Data Frame Consumo Stress
df_hist_stress_cons = df_hist[df_hist['info']=='% Utilização Limite Stress']
# Data Frame de Retorno
df_hist_ret = df_hist[df_hist['info']=='Retorno']
# Obtendo todas as datas (removendo duplicados)
#datas = df_hist.dtcalculo.drop_duplicates(keep='first').reset_index(drop=True)
datas = pd.DataFrame(list(query_data.values()))
datas = datas.dtcalculo.drop_duplicates(keep='first').reset_index(drop=True)
# Obtendo o nome de todos os fundos (removendo duplicados)
fundos = list(df_hist.cdcarteira.drop_duplicates(keep='first').reset_index(drop=True))
# Criando um data frame unico com todas as informacoes a serem utilizadas
df_hist_saida = pd.DataFrame(columns=['dtcalculo', 'cdcarteira'])
# Criando um data frame com o numero de linhas igual a fundos * datas
for fundo in fundos:
# Data Frame temporario
df_temp = pd.DataFrame(columns=['dtcalculo', 'cdcarteira'])
# Copiando as datas
df_temp['dtcalculo'] = datas
# Inserindo o nome do fundo
df_temp['cdcarteira'] = [fundo] * len(datas)
# Inserindo dados do temp no data frame de saida
df_hist_saida = df_hist_saida.append(df_temp)
# Resetando index e criando uma chave de concateno para o dataframe de saida
df_hist_saida = df_hist_saida.reset_index(drop=True)
df_hist_saida['concat'] = df_hist_saida['dtcalculo'].astype(str) + df_hist_saida['cdcarteira']
# Criando coluna de var pl
df_hist_saida = df_hist_saida.merge(df_hist_var[['concat', 'valor']], on='concat', how='left')
df_hist_saida = df_hist_saida.rename(columns={'valor': 'var_pl'})
# Criando coluna de var pl
df_hist_saida = df_hist_saida.merge(df_hist_stress[['concat', 'valor']], on='concat', how='left')
df_hist_saida = df_hist_saida.rename(columns={'valor': 'stress_pl'})
# Criando coluna de consumo var
df_hist_saida = df_hist_saida.merge(df_hist_var_cons[['concat', 'valor']], on='concat', how='left')
df_hist_saida = df_hist_saida.rename(columns={'valor': 'var_cons'})
# Criando coluna de consumo stress
df_hist_saida = df_hist_saida.merge(df_hist_stress_cons[['concat', 'valor']], on='concat', how='left')
df_hist_saida = df_hist_saida.rename(columns={'valor': 'stress_cons'})
# Criando coluna de retorno
df_hist_saida = df_hist_saida.merge(df_hist_stress_cons[['concat', 'valor']], on='concat', how='left')
df_hist_saida = df_hist_saida.rename(columns={'valor': 'retorno'})
# Removendo a coluna concatenado
df_hist_saida = df_hist_saida.drop('concat', axis=1)
# Substituindo NaN por none
df_hist_saida = df_hist_saida.fillna('None')
# Criando dicionarios de saida
dict_var_pl_hist = dict()
dict_stress_pl_hist = dict()
dict_var_cons_hist = dict()
dict_stress_cons_hist = dict()
for fundo in fundos:
dict_var_pl_hist[fundo] = list(df_hist_saida[df_hist_saida['cdcarteira'] == fundo].var_pl)
dict_stress_pl_hist[fundo] = list(df_hist_saida[df_hist_saida['cdcarteira'] == fundo].stress_pl)
dict_var_cons_hist[fundo] = list(df_hist_saida[df_hist_saida['cdcarteira'] == fundo].var_cons)
dict_stress_cons_hist[fundo] = list(df_hist_saida[df_hist_saida['cdcarteira'] == fundo].stress_cons)
# Lista contendo todas as datas utilizadas
lista_datas = list(datas.astype(str))
# Alertas
alerta_1 = [70] * len(datas)
alerta_2 = [85] * len(datas)
alerta_3 = [100] * len(datas)
# Flagship
context ={'query_carteira': query_carteira,
'fundos': json.dumps(fundos),
'util_var': json.dumps(util_var),
'util_stress': json.dumps(util_stress,),
'dict_var_pl_hist': json.dumps(dict_var_pl_hist, default=dict),
'dict_stress_pl_hist': json.dumps(dict_stress_pl_hist, default=dict),
'dict_var_cons_hist': json.dumps(dict_var_cons_hist, default=dict),
'dict_stress_cons_hist': json.dumps(dict_stress_cons_hist, default=dict),
'datas_hist': json.dumps(lista_datas, default=str),
'alerta_1': json.dumps(alerta_1),
'alerta_2': json.dumps(alerta_2),
'alerta_3': json.dumps(alerta_3),
}
return render(request, 'dash_solutions_completo.html', context)
urls.py
# Importamos a função index() definida no arquivo views.py
from portal_riscos.views import *
from django.urls import path
from django.contrib.auth.views import LoginView
app_name = 'portal_riscos'
# urlpatterns contém a lista de roteamento URLs
urlpatterns = [
# Dashboard Solutions
path('', FlagshipSolutions, name='dash_solutions'),
path('solutions_fundos/<pk>/<cdcarteira>', VisualizaFundoSolutions.as_view(), name='solutions_fundos')
]
我要单击并重定向的表的一部分
<a href="{% url 'portal_riscos:solutions_fundos' fundo.dtcalculo fundo.cdcarteira %}"
class="btn btn-light btn-sm">Atualizar</a>
那是我得到的错误:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/solutions_fundos/2019-01-14/FICFI52865
Django Version: 2.1.2
Python Version: 3.6.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'portal_riscos',
'widget_tweaks',
'django.contrib.humanize']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\views\generic\base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\views\generic\base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get
189. self.object = self.get_object()
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\views\generic\detail.py" in get_object
52. obj = queryset.get()
File "C:\Users\TBMEPYG\AppData\Local\Continuum\Anaconda3\lib\site-packages\django\db\models\query.py" in get
403. (self.model._meta.object_name, num)
Exception Type: MultipleObjectsReturned at /solutions_fundos/2019-01-14/FICFI52865
Exception Value: get() returned more than one RmDadoscarteira -- it returned 21!
任何人对我该怎么办?
谢谢
答案 0 :(得分:2)
这与拥有两个主键没有特别关系。如果您需要使用基本的pk或slug查找之外的其他方法,而在基于类的视图中获取对象,则需要定义get_object
方法。
class VisualizaFundoSolutions(UpdateView):
...
def get_object(self):
return RmDadoscarteira.objects.get(pk=self.kwargs["pk"], cdcarteira=self.kwargs["cdcarteira"])