我正在构建一个应用程序,允许用户创建场景,然后创建关联的电子邮件,t,调用和交易场景。
与场景和通信有1:很多关系。我遇到的问题是我希望用户能够单击该方案,然后显示已过滤的通信列表,每个通信源都是一个选项卡。我过滤通信的方式是基于对象上的外键的id。但是,如果数据源没有条目,我会收到"没有反向匹配"因为我正在使用来自第一个对象的方案ID,并且如果该方案没有通信则不存在。
除了删除我喜欢的标签之外,我对最好的方法感到难过。
如果我遗失任何内容,请告诉我,我对编程相对较新,对Django来说也很新。
from __future__ import unicode_literals
from django.db import models
from django.core.urlresolvers import reverse
class Scenario(models.Model):
name = models.CharField(max_length=256, blank=False, null=False, unique=True)
description = models.TextField(max_length=1000)
def get_absolute_url(self):
return reverse('scenarios:detail', kwargs={'pk': self.pk})
def __unicode__(self):
return self.name
class Email(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE )
recipient_email = models.EmailField()
sender_email = models.EmailField()
subject = models.CharField(blank=True, null=False, max_length=256)
body = models.TextField(blank=True, null=False, max_length=2048)
# timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
# updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def get_absolute_url(self):
return reverse('scenarios:email-index')
def __unicode__(self):
return self.sender_email + ' ' + self.recipient_email + ' ' + self.subject
class InstantMessage(models.Model):
NETWORKS = (
('Yahoo', 'Yahoo'),
('MSN', 'MSN'),
('Skype', 'Skype')
)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
description = models.CharField(max_length=256, null=False, blank=False)
network = models.CharField(max_length=50, null=False, blank=False, choices=NETWORKS)
room = models.CharField(max_length=100, null=False, blank=False)
starttime = models.TimeField(blank=False, null=False)
endtime = models.TimeField(blank=False, null=False)
participant1 = models.CharField(max_length=256, null=False, blank=False)
participant2 = models.CharField(max_length=256, null=False, blank=False)
chatcsv = models.FileField(upload_to='chatfiles')
def get_absolute_url(self):
return reverse('scenarios:im-index')
def __unicode__(self):
return "Network=" + self.network + " Description:" + self.description
class VoiceCall(models.Model):
DIRECTION = (
('outbound', 'Outbound'),
('inbound', 'Inbound')
)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
description = models.CharField(max_length=256, null=False, blank=False)
direction = models.CharField(choices=DIRECTION, null=False, blank=False, default="Outbound", max_length=15)
starttime = models.TimeField(blank=False, null=False)
endtime = models.TimeField(blank=False, null=False)
traderid = models.CharField(max_length=50,blank=False, null=False)
diallednumber = models.BigIntegerField(blank=True, null=True)
cli = models.BigIntegerField(blank=True, null=True)
nameofcaller = models.CharField(max_length=100, blank=True, null=True)
nameofline = models.CharField(max_length=100, blank=True, null=True)
wavfile = models.FileField(upload_to='voice')
transcript = models.FileField(blank=True, null=True, upload_to='voice')
bagofwords = models.FileField(blank=True, null=True, upload_to='voice')
def get_absolute_url(self):
return reverse('scenarios:call-index')
def __unicode__(self):
return self.description
class Trade(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
tradeprefix = models.CharField(max_length=6, null=False, blank=False)
trader = models.CharField(max_length=256, null=False, blank=False)
sales = models.CharField(max_length=256, null=False, blank=False)
counterpartyid = models.CharField(max_length=256, null=False, blank=False)
counterpartyname = models.CharField(max_length=256, null=False, blank=False)
brokerid = models.CharField(max_length=256, null=False, blank=False)
brokername = models.CharField(max_length=256, null=False, blank=False)
isevent = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse('scenarios:trade-index')
# def __unicode__(self):
# return self.description
class Mobile(models.Model):
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
displayname = models.CharField(max_length=100, null=False, blank=False)
email = models.EmailField()
tonumber = models.BigIntegerField(blank=True, null=True)
fromnumber = models.BigIntegerField(blank=True, null=True)
message = models.CharField(blank=True, null=False, max_length=1024)
def get_absolute_url(self):
return reverse('scenarios:mobile-index')
class IMScenarioList(generic.ListView):
model = InstantMessage
template_name = 'scenarios/im_filtered.html'
context_object_name = 'scenario_ims'
def get_queryset(self):
return InstantMessage.objects.filter(scenario=self.kwargs['pk'])
class CallScenario(generic.ListView):
model = VoiceCall
template_name = 'scenarios/call_filtered.html'
context_object_name = 'scenario_calls'
def get_queryset(self):
return VoiceCall.objects.filter(scenario=self.kwargs['pk'])
class MobileScenario(generic.ListView):
model = Mobile
template_name = 'scenarios/mobile_filtered.html'
context_object_name = 'scenario_mobiles'
def get_queryset(self):
return Mobile.objects.filter(scenario=self.kwargs['pk'])
class TradeScenario(generic.ListView):
model = Trade
template_name = 'scenarios/trades_filtered.html'
context_object_name = 'trades'
def get_queryset(self):
return Trade.objects.filter(scenario=self.kwargs['pk'])
url(r'^(?P<pk>[0-9]+)/email/$', views.EmailScenarioList.as_view(), name='email-scenario'),
# Instant Messages
url(r'^im/$', views.IMList.as_view(), name='im-index'),
url(r'^im/add/$', views.IMCreate.as_view(), name='im-create'),
url(r'^im/(?P<pk>[0-9]+)/update/$', views.IMUpdate.as_view(), name='im-update'),
url(r'^im/(?P<pk>[0-9]+)/delete/$', views.IMDelete.as_view(), name='im-delete'),
url(r'^(?P<pk>[0-9]+)/im/$', views.IMScenarioList.as_view(), name='im-scenario'),
# Voice Calls
url(r'^calls/$', views.CallList.as_view(), name='call-index'),
url(r'calls/add/$', views.CallCreate.as_view(), name='call-create'),
url(r'^calls/(?P<pk>[0-9]+)/update/$', views.CallUpdate.as_view(), name='call-update'),
url(r'^calls/(?P<pk>[0-9]+)/delete/$', views.CallDelete.as_view(), name='call-delete'),
url(r'^(?P<pk>[0-9]+)/voice/$', views.CallScenario.as_view(), name='call-scenario'),
# trades
url(r'^trades/$', views.TradeList.as_view(), name='trade-index'),
url(r'^trades/add/$', views.TradeCreate.as_view(), name='trade-create'),
url(r'^trades/(?P<pk>[0-9]+)/update/$', views.TradeUpdate.as_view(), name='trade-update'),
url(r'^trades/(?P<pk>[0-9]+)/delete/$', views.TradeDelete.as_view(), name='trade-delete'),
url(r'^(?P<pk>[0-9]+)/trade/$', views.TradeScenario.as_view(), name='trade-scenario'),
# mobile
url(r'^mobile/$', views.MobileList.as_view(), name='mobile-index'),
url(r'^mobile/add/$', views.MobileCreate.as_view(), name='mobile-create'),
url(r'^mobile/(?P<pk>[0-9]+)/update/$', views.MobileUpdate.as_view(), name='mobile-update'),
url(r'^mobile/(?P<pk>[0-9]+)/delete/$', views.MobileDelete.as_view(), name='mobile-delete'),
url(r'^(?P<pk>[0-9]+)/mobile/$', views.MobileScenario.as_view(), name='mobile-scenario'),
{% extends 'base.html' %}
{% block content %}
<div class="container">
<table id="myTable" class="tablesorter tablesorter-bootstrap">
<thead>
<tr>
<th class="first-name filter-select" data-placeholder="Select a Scenario">Scenario</th>
<th></th>
<th>Trade Prefix</th>
<th>Trader</th>
<th>Sales</th>
<th>Counterparty ID</th>
<th class="first-name filter-select" data-placeholder="Select Counterparty">Counterparty Name</th>
<th>Broker ID</th>
<th></th>
<th class="first-name filter-select" data-placeholder="Select Broker">Broker Name</th>
<th class="first-name filter-select" data-placeholder="IsEvent">IsEvent</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for trade in trades %}
<tr>
<td data-toggle="tooltip" title="Description: {{trade.scenario.description}}">{{trade.scenario}}</td>
<td></td>
<td>{{trade.tradeprefix}}</td>
<td>{{trade.trader}}</td>
<td>{{trade.sales}}</td>
<td>{{trade.counterpartyid}}</td>
<td>{{trade.counterpartyname}}</td>
<td>{{trade.brokerid}}</td>
<td></td>
<td>{{trade.brokername}}</td>
<td>{{trade.isevent}}</td>
<td>
<a href="{% url 'scenarios:trade-update' trade.id %}">
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-pencil" />
</button>
</a>
</td>
<td><form action="{% url 'scenarios:trade-delete' pk=trade.id %}" method="post">
{% csrf_token %}
<input type="hidden" name="call_id" value="{{ trade.id}}"/>
<button type="submit" class="btn btn-default btn-sm" onclick="return confirm('Are you sure you want to delete {{trade.description}}?')">
<span class="glyphicon glyphicon-trash" />
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'scenarios:trade-create' %}">
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-plus" />
</button>
</a> Add Trade
<br>
<button type="button" class="btn btn-default btn-sm" value="Back" onClick="javascript:history.go(-1);">
<span class="glyphicon glyphicon-backward" />
</button>
</div>
{% endblock %}
{% extends 'scenarios/trade_index.html' %}
{% block content %}
{% with trades|first as first_trade %}
<ul class="nav nav-pills">
<li class="active"><a href="{% url 'scenarios:trade-scenario' pk=first_trade.scenario.id %}">trades</a></li>
<li><a href="{% url 'scenarios:email-scenario' pk=first_trade.scenario.id %}">emails</a></li>
<li><a href="{% url 'scenarios:im-scenario' pk=first_trade.scenario.id %}">instant messages</a></li>
<li><a href="{% url 'scenarios:call-scenario' pk=first_trade.scenario.id %}">voice</a></li>
<li><a href="{% url 'scenarios:mobile-scenario' pk=first_trade.scenario.id %}">mobile</a></li>
</ul>
{% endwith %}
{{ block.super }}
{% endblock %}
答案 0 :(得分:1)
现在在trades_filtered.html
中,您获取给定scenario
的ID并使用该ID手动构建您的五个网址。如果是我,我会使用自定义模型方法来确定是否需要首先生成URL。
class Scenario(models.Model):
name = models.CharField(max_length=256, blank=False, null=False, unique=True)
description = models.TextField(max_length=1000)
def generate_trade_url(self):
if self.trade_set.exists():
return reverse('scenarios:trade-scenario', kwargs={'pk':self.pk})
return None
def generate_email_url(self):
...
对于要生成的每个网址,您需要一个这样的方法。您可以在视图(首选)或模板(更简单但更慢)中使用此逻辑,以便仅在URL有效时动态生成URL。
编辑:我刚刚第二次看了这个答案。我在null=False
字段定义中包含name
,因为它位于原始字段中,但要注意它实际上并没有对CharField
执行任何有用的操作。 Django不对这些字段使用空值,而是将它们存储为''
(空字符串)。