2016-09-22 5 views
0

私は、ユーザーがシナリオを作成し、シナリオに関連付けられた電子メール、通話、通話、取引を作成できるアプリケーションを構築しています。外部キーIDを取得できません

シナリオと通信に1対多の関係があります。私が抱えている問題は、ユーザがシナリオをクリックできるようにし、それから通信のフィルタリングされたリストを表示し、各通信ソースがタブであることです。私が通信をフィルタリングする方法は、オブジェクト上の外部キーのIDに基づいています。しかし、データソースのエントリがない場合は、最初のオブジェクトからシナリオIDを使用しているため、「逆マッチなし」が表示され、そのシナリオの通信がない場合は存在しません。

私が好きなタブを削除する以外に、これを行うための最良の方法は何かに困惑しています。

私は何かが不足している場合は教えてください、私はプログラミングに比較的新しいとDjangoには非常に新しいです。

models.py

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') 

views.py

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']) 

urls.py

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'), 

テンプレート

trade_index.html

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

trades_filtered.html

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

あなたのモデルは何ですか? –

+0

こんにちはマイケルl、すみません、私はそれを投稿しませんでした。モデルを使って編集しました。 ありがとう、Chris –

+1

あなたのシナリオはかなり複雑です。起こっていることを視覚化するためにそれに精通していない人にとっては、難しいことです。解決しようとしている設計上の問題だけを示す最小限の例を試してみてください。ほんの数少ないシンプルなモデルとビューで。しばしば、簡単な例を考え出すと、答えがわかります。 –

答えて

1

あなたが与えられたscenarioのIDを取得し、手動で5つのURLを構築するためにその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を生成することができます。

編集:私はこの答えをもう一度見ました。私はnameフィールド定義の中にnull=Falseを含めました。オリジナルであったので、実際にはCharFieldで何も役に立たないことに注意してください。 Djangoはそれらのフィールドにnull値を使用せず、代わりに''(空文字列)として保存します。

+0

これはアイデアのように思えます。私は今、ビューでメソッドを使用する方法を理解する必要があります。この瞬間、私は何をするのか分かりません。しかし、赤ちゃんのステップは....それはbashを与えるでしょう。 –

+0

私は喜んで助けてくれるでしょうが、コメント内の拡張された議論は一般的には眉をひそめます。コンテキストベースのデータをクラスベースのビューに追加しようとしている場合は、https:// docsを起動します。djangoproject.com/en/1.10/topics/class-based-views/generic-display/#adding-extra-contextその問題に遭遇した場合は、新しい質問を開いて私にタグを付けてください(私は私のウェブサイトhttp://souldeux.comで私にメッセージしてください。 – souldeux

+0

私はおそらくこれを間違えました。私はこの道を下り、それはうまくいきました、余分なコードがたくさんありました。最終的に、nav-pillsと一緒にiframeを使用する必要がなくなりました。コードをiframeの例を使用して元に戻してしまいました: '

  • trades
  • '。これは正常に動作します。 –

    関連する問題