【发布时间】:2019-11-28 21:08:01
【问题描述】:
我正在尝试制作一个 Django 应用程序,它允许查看客户的所有金融投资组合(在本例中是各种股票、共同基金和“其他”,如 401k)
我有一个由客户在我的 views.py 文件中创建的共同基金查询集,我试图将其传递给 html 模板并呈现列表。不过,我在标题中遇到了错误:'NoneType' 对象没有属性'get'。
我已经通过打印语句验证了 QuerySet 是 not 类型的 None,并且当我将它存储在我的视图中的变量中时,我想要使用的所有数据都会正确返回。
我有一个适用于股票的一切功能,它具有相同的功能,可以正常工作,所以我无法弄清楚其中的区别以及为什么一个有效而另一个无效。什么会导致这个错误?
以下是我认为直接相关的代码块和错误消息。完整代码在:https://github.com/apalmesano2/assignment2_part2
错误
Internal Server Error: /customer/2/portfolio/
Traceback (most recent call last):
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
response = get_response(request)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\andre\isqa8380\efsd-local\efs\portfolio\views.py", line 270, in portfolio
'mutual_funds': mutual_funds,
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\shortcuts.py", line 36, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\loader.py", line 62, in render_to_string
return template.render(context, request)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 175, in render
return self._render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 943, in render
bit = node.render_annotated(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 910, in render_annotated
return self.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\loader_tags.py", line 155, in render
return compiled_parent._render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 167, in _render
return self.nodelist.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 943, in render
bit = node.render_annotated(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 910, in render_annotated
return self.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\loader_tags.py", line 67, in render
result = block.nodelist.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 943, in render
bit = node.render_annotated(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 910, in render_annotated
return self.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\defaulttags.py", line 211, in render
nodelist.append(node.render_annotated(context))
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 910, in render_annotated
return self.render(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 993, in render
output = self.filter_expression.resolve(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 676, in resolve
obj = self.var.resolve(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 802, in resolve
value = self._resolve_lookup(context)
File "C:\Users\andre\isqa8380\efsd-local\lib\site-packages\django\template\base.py", line 864, in _resolve_lookup
current = current()
File "C:\Users\andre\isqa8380\efsd-local\efs\portfolio\models.py", line 114, in current_mutual_fund_price
mf_open_price = float(mf_json_data.get('Global Quote').get('05. price'))
AttributeError: 'NoneType' object has no attribute 'get'
models.py
class Stock(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='stocks')
symbol = models.CharField(max_length=10)
name = models.CharField(max_length=50)
shares = models.DecimalField(max_digits=10, decimal_places=1)
purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
purchase_date = models.DateField(default=timezone.now, blank=True, null=True)
def created(self):
self.recent_date = timezone.now()
self.save()
def __str__(self):
return str(self.customer)
def initial_stock_value(self):
return self.shares * self.purchase_price
def current_stock_price(self):
symbol_f = str(self.symbol)
main_api = 'https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols='
api_key = '&apikey= <MY_API_KEY>'
url = main_api + symbol_f + api_key
json_data = requests.get(url).json()
open_price = float(json_data["Stock Quotes"][0]["2. price"])
share_value = open_price
return share_value
def current_stock_value(self):
return round((Decimal(self.current_stock_price()) * Decimal(self.shares)), 3)
class MutualFund(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='mutual_funds')
symbol = models.CharField(max_length=10)
name = models.CharField(max_length=50)
shares = models.DecimalField(max_digits=10, decimal_places=1)
purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
purchase_date = models.DateField(default=timezone.now, blank=True, null=True)
def created(self):
self.recent_date = timezone.now()
self.save()
def __str__(self):
return str(self.customer)
def initial_mutual_fund_value(self):
return self.shares * self.purchase_price
def current_mutual_fund_price(self):
mf_symbol_f = str(self.symbol)
mf_main_api = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol='
mf_api_key = '&apikey= <MY_API_KEY>'
mf_url = mf_main_api + mf_symbol_f + mf_api_key
mf_json_data = requests.get(mf_url).json()
mf_open_price = float(mf_json_data.get('Global Quote').get('05. price'))
mf_share_value = mf_open_price
return mf_share_value
def current_mutual_fund_value(self):
return round((Decimal(self.current_mutual_fund_price()) * Decimal(self.shares)), 3)
views.py
def portfolio(request, pk):
customer = get_object_or_404(Customer, pk=pk)
customers = Customer.objects.filter(created_date__lte=timezone.now())
investments = Investment.objects.filter(customer=pk)
stocks = Stock.objects.filter(customer=pk)
mutual_funds = MutualFund.objects.filter(customer=pk)
sum_recent_value = Investment.objects.filter(customer=pk).aggregate(Sum('recent_value'))
sum_acquired_value = Investment.objects.filter(customer=pk).aggregate(Sum('acquired_value'))
# overall_investment_results = sum_recent_value-sum_acquired_value
# Initialize the value of the stocks
sum_current_stocks_value = 0
sum_of_initial_stock_value = 0
sum_current_mutual_fund_value = 0
sum_initial_mutual_fund_value = 0
# Loop through each stock and add the value to the total
for stock in stocks:
sum_current_stocks_value += stock.current_stock_value()
sum_of_initial_stock_value += stock.initial_stock_value()
for mutual_fund in mutual_funds:
sum_current_mutual_fund_value += mutual_fund.current_mutual_fund_value()
sum_initial_mutual_fund_value += mutual_fund.initial_mutual_fund_value()
sum_recent_investments = sum_recent_value.get('recent_value__sum')
sum_acquired_investments = sum_acquired_value.get('acquired_value__sum')
portfolio_initial_total = sum_of_initial_stock_value + sum_initial_mutual_fund_value + sum_acquired_investments
portfolio_current_total = sum_current_stocks_value + sum_current_mutual_fund_value + sum_recent_investments
return render(request, 'portfolio/portfolio.html', {'customers': customers,
'investments': investments,
'stocks': stocks,
'sum_acquired_value': sum_acquired_value,
'sum_recent_value': sum_recent_value,
'sum_current_stocks_value': sum_current_stocks_value,
'sum_of_initial_stock_value': sum_of_initial_stock_value,
'portfolio_initial_total': portfolio_initial_total,
'portfolio_current_total': portfolio_current_total,
'sum_recent_investments': sum_recent_investments,
'sum_acquired_investments': sum_acquired_investments,
'sum_current_mutual_fund_value': sum_current_mutual_fund_value,
'sum_initial_mutual_fund_value': sum_initial_mutual_fund_value,
'mutual_funds': mutual_funds,
})
portfolio.html
<div class="row">
<h2 style="padding-left: 15Px">Mutual Fund Information</h2>
</div>
<div class="row">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr class="bg-info">
<th>Customer</th>
<th>Symbol</th>
<th>Name</th>
<th>Shares</th>
<th>Initial Mutual Fund Price</th>
<th>Initial Mutual Fund Value</th>
<th>Current Mutual Fund Price</th>
<th>Current Mutual Fund Value</th>
<th>Results</th>
</tr>
</thead>
<tbody>
{% for mutual_fund in mutual_funds %}
<tr>
<td>{{ mutual_fund.customer }}</td>
<td>{{ mutual_fund.symbol }}</td>
<td>{{ mutual_fund.name }}</td>
<td>{{ mutual_fund.shares|intcomma }}</td>
<td>{{ mutual_fund.purchase_price|intcomma }}</td>
<td>{{ mutual_fund.initial_mutual_fund_value|intcomma }}</td>
<td>{{ mutual_fund.current_mutual_fund_price|intcomma }}</td>
<<td>{{ mutual_fund.current_mutual_fund_value|intcomma }}</td>
<td>{{ mutual_fund.current_mutual_fund_value|sub:mutual_fund.initial_mutual_fund_value|intcomma }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr class="bg-info">
<th>Total of Initial Mutual Funds</th>
<th>Total of Current Mutual Funds</th>
<th>Results</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ sum_initial_mutual_fund_value|intcomma }}</td>
<td>{{ sum_current_mutual_fund_value|intcomma }}</td>
<td>{{ sum_current_mutual_fund_value|sub:sum_initial_mutual_fund_value|intcomma }}</td>
</tr>
</tbody>
</table>
</div>
【问题讨论】:
-
修复你的缩进,提供一个驱动程序来引发错误,并给我们整个错误信息——包括回溯。删除多余的代码和数据。 那么我们有一个很好的起点来寻找问题。