1

次のコード例では、コントローラーからモデルへのリクエストの受け渡しをどのように解決したかを示しています。これを行うより良い方法はありますか?

モデル/MyModel.py

from google.appengine.ext import db

class MyModel(db.model):
    a = db.StringProperty(required=True)
    b = db.StringProperty(required=True)
    c = db.StringProperty(required=True)

class Update:
    def __init__(self, x)
        self.x = x

    def do_something(self)
        myquery = db.GqlQuery('SELECT * FROM MyModel WHERE a = :1' self.x)
        v = myquery.get()

        if not v:
            somevalue = MyModel(a = self.request.get('a'), # Doesn't work unless
                                b = self.request.get('b'), # the request has been
                                c = self.request.get('c')) # passed
            somevalue.put()

コントローラー/MyController.py

import webapp2
from models.MyModel import Update

class WebHandler(webapp2.RequestHandler):
    def get(self):
        var_x = "string"
        var_y = "string"
        z = Update(var_x)
        z.request = self.request  # <--- Is there a better way?
        z.do_something()

編集: (2012 年 5 月 30 日) リクエスト変数をモデルに引数として渡す関数を作成しました。すべての繰り返しを回避する Python マジックがあることを期待していましたが、見つかりませんでした。

4

3 に答える 3

4

リクエストをモデルに引き渡すということは、モデルとコントローラーが混在していることを意味します。

通常、モデルはそれがリクエストであることさえ認識すべきではありません。リクエストからパラメーターを取得するのはコントローラーの仕事であり、モデルではありません。メソッドがパラメーターを処理する必要がある場合do_somethingは、パラメーターを引数として取得し、結果 (通常はエンティティ) を返す必要があります。

于 2012-05-12T19:10:52.167 に答える
2

もう少しカプセル化が必要です。別のレベルの抽象化が役立ちます。

、、および属性またはプロパティを使用MyModelして、永続化に使用している実際のものを表すクラスを作成します。abc

class Thing(object):

   def __init__(a, b, c):
      self.a = a
      self.b = b
      self.c = c 

このクラスは、リクエスト、データストア、永続性について何も知りません。モノ自体を取り巻くすべての実際のビジネス ロジックが存在する場所です。

リクエストやデータベースを必要とせずにこのクラスをインスタンス化でき、GAE の配管をモックアウトすることなく、すべてのビジネス ロジックを単体テストできます。

次に、このことをインスタンス化するリクエストハンドラーにコードを記述できます。次に例を示します。

def get(request):
  thing = Thing(a=request.get('a'), b=request.get('b'), c=request.get('c'))
  u = Update(some_params)
  u.do_something(thing)

ものを配置するクラスメソッドを追加できますMyModel。たとえば、次のようになります。

@classmethod
def put_thing(thing):
  model = MyModel(a=thing.a, b=thing.b, c=thing.c)
  model.put()

データベースに追加する必要がある場合は、do_somethingロジックを呼び出すだけです。MyModel.put_thing(thing)

于 2012-05-12T20:30:56.723 に答える
1

@classmethod デコレータを使用して MyModel クラスにクラス メソッドとして update を追加し、MyModel.update(a=x) を呼び出すことができます。

于 2012-05-12T18:56:34.333 に答える