2

これらのモデルがあるとしましょう:

class A(models.Model):
    name = models.CharField(max_length=32)
    b = models.ForeignKey("B", null=True)
    def __unicode__(self):
        return self.name

class B(models.Model):
    name = models.CharField(max_length=32)
    def __unicode__(self):
        return self.name

そして、このビュー:

def DisplayIt(request):
    html = ""
    for a in A.objects.all():
        html += "<input type='text' value='" + a.b.name + "' />"

これは、すべての A がフィールド b の B への参照を持っている限り、正常に機能します。しかし、私は b 参照フィールドに null=True を持っています。b が None の場合、NoneType に関数名がないという例外がスローされますが、これは完全に予想されることです。

明らかに、私はこれを行うことができます:

def DisplayIt(request):
    somestring = ""
    for a in A.objects.all():
        if a.b is not None:
            somestring += a.b.name

しかし、必要がなければ、これはしたくありません。if a.b is not None:では、各ループに an を入れずに、b が None の場合に b.name または None を取得する方法はありますか? 私の実際の例はもっと複雑で、実際のデータベース フィールドから表示用の一時オブジェクトを作成しています。そこに到達するための別の組み込み関数でした。これらの外部フィールドが存在する場合はそれらを取得し、存在しない場合は空白にするクラス メソッドを作成することもできますが、これが最善の方法であるかどうかもわかりません。

4

2 に答える 2

3

データベースに任せてください。

相互関係フィルターを使用して、 nullA以外の aをb持つすべてを取得します。name

def DisplayIt(request):
    somestring = ""
    for a in A.objects.filter(b__name__isnull=False):
        somestring += a.b.name

が None のときにダミー値が含まれるようにするにa.bは、次のようにします。

def DisplayIt(request):
    somestring = ""
    for a in A.objects.filter(b__name__isnull=False):
        somestring += a.b.name
    for a in A.objects.filter(b__name__isnull=True):
        somestring += "dummy value for missing b.name"



また、補足として、文字列の連結をそのように行わないでください。Pythonの文字列は可変ではないため、非常に非効率的です。以下ははるかに優れています。

def DisplayIt(request):
    stringparts = []
    for a in A.objects.filter(b__name__isnull=False):
        stringparts.append(a.b.name)
    for a in A.objects.filter(b__name__isnull=True):
        stringparts.append("dummy value for missing b.name")
    ''.join(stringparts)



2 つ目の補足事項: 上記のコードは、for ループの各反復で ab を取得するクエリを実行します。それは超遅いかもしれません。select_related一度にすべてを取得するために使用することを検討してください。ただし、注意してください。インデックスが正しく設定されていないと、これも遅くなる可能性があります。これを有効にした後、クエリをスニッフィングし、クエリ プランナーと質の高い時間を費やして、厄介なインデックスなしのルックアップを行っていないことを確認します。

改訂されたコード:

def DisplayIt(request):
    stringparts = []
    for a in A.objects.filter(b__name__isnull=False).select_related():
        stringparts.append(a.b.name)
    for a in A.objects.filter(b__name__isnull=True).select_related():
        stringparts.append("dummy value for missing b.name")
    ''.join(stringparts)
于 2012-04-10T22:42:43.840 に答える
3

B がある場合とない場合がある A のインスタンスが必要であるというコメントから構築します。これをハックして機能させることができますが、これは通常ひどい考えです。避けたい、長々とした pythonic の方法を使用してください。しかし、これはあなたが望むことをするための悪い方法です:

a.__dict__.get('b',{'name':None}).name

これは、すべての属性がdictオブジェクトの実際のインスタンスのオブジェクトに格納されているという事実を利用しています。標準のディクショナリ アクセサを使用して、または関心のある属性を含むディクショナリget()を返します。b

また、django/python は古い学校の PHP ではありません。ここ数週間、stackoverflow でこれを何回目にしたか信じられませんが... HTML を生成するために文字列を連結しないでください!! それがテンプレート言語の目的です。これを使って。あなたが今していることを止めてください。やめてやめてやめて。テンプレートを使用し、ビューに HTML を書き込もうとしないでください。それは証明可能な間違ったことなので、やめてください。ただやめてください。

于 2012-04-10T23:11:55.290 に答える