1

process_responseの後にDjangoは応答を平坦化しますか?

私はこのモデルを持っています(簡略版):

class Ticket(models.Model):
    uuid = UUIDField(primary_key = True)
    is_active = models.BooleanField(default = False)
    remains = models.IntegerField(default = 2)

    def __unicode__(self):
        return '%s' % (self.is_active)

およびミドルウェア (簡略化):

class TicketMiddleware(object):
    def process_request(self, request):
        # ...
        try:
            request.ticket = Ticket.objects.get(uuid_exact=request.GET['ticket'], is_active=True)
            print '%s %d' % (request.ticket.is_active, request.ticket.remains)
            # first case:
            return HttpResponse(request.ticket)
            # second case:
            #return HttpResponse(request.ticket.is_active)
        except Ticket.DoesNotExists:
            return HttpResponseForbidden()

    def process_response(self, request, response):
        if request.ticket is not None and request.ticket.remains > 0:
            request.ticket.remains -= 1
            if request.ticket.remains == 0:
                request.ticket.is_active = False
            request.ticket.save()
        return response

最初のケースでは、4 番目のリクエストで禁止ページを取得しました。

   RESPONSE     PRINT
1: True         True 2
2: False        True 1
3: False        True 1
4: Forbidden

2 番目のケースでは、3 番目のリクエストで禁止ページを取得しました。

   RESPONSE     PRINT
1: True         True 2
2: True         True 1
3: Forbidden

そして、この2番目のケースは私が望む方法です。適切にフローするために、最初にモデルを文字列化する必要があるのはなぜですか? 私が誤解したことは何ですか?

django.VERSION = (1, 2, 3, 'final', 0)

編集

問題が見つかりました。実際のコードでは、django.contrib.auth.models.User に外部キーを使用し、関連するユーザーのユーザー名でチケット モデルをユニコーディングします。

class Ticket(models.Model):
    # ...
    user = models.ForeignKey(User)

    def __unicode__(self):
        # this works as expected
        return u'%s' % (self.is_active)
        # with this I have unexpected third step in first case
        # but I dont understand why
        #return u'%s %s' % (self.user.username, self.is_active)
4

1 に答える 1

3

最初のケースが 2 回表示されるとは思えませんFalse。あなたのコードで簡単なテストを作成しました。最初のケースで表示されます。

1: True
2: False
3: Forbidden

これは予想される動作です。process_responseがデータを変更し、2 番目の呼び出しでチケットを保存する限りis_active、3 番目の呼び出しで False を返す方法がわかりません... ticket.remains が何らかの方法で変更されない限り。process_responseここに示されているコードでは、 でチケットを保存し、is_active=Falseその後のリクエストprocess_requestでリダイレクトしないようにする方法がわかりませんForbidden... どの Django バージョンを使用していますか? も印刷ticket.remainsして、__unicode__()どのように変化するかを確認してください...

False最初のケースで 2 番目の呼び出しを取得する理由は、モデル インスタンスを渡すためです。

return HttpResponse(request.ticket)

ticket.__unicode__()が呼び出された後、のコンテンツをクライアントprocess_responseに最終的に書き込む際に、 が呼び出されます。HttpResponse()そして、最初のシナリオticket.is_activeでは が で変更されているprocess_responseため、 ticket.__unicode__()が最終的に呼び出されると、 の変更された値が取得されticket.is_activeますFalse

2 番目のシナリオで__unicode__は、 が process_request で明示的に呼び出され、'True' に評価されます。

于 2012-07-31T11:31:43.320 に答える