2017-03-29 10 views
0

私はモデルフィールドのデフォルト値(および他のkwargsからは)よりダイナミックにするためにしようとしているので、私はそのための関数を作った:Djangoのモデル - 引数付き渡す関数オブジェクト

def get_latest_id(cls, text, *args): 
    try: 
     ret = globals()[cls].objects.latest('id').id + 1 
     return text.format(ret, args) 
    except: 
     return text.format(1, args) 

が、私はこれを使用していましたいくつかのフィールドのデフォルトとして機能しますが、私は機能するように関数を伝える引数が必要です。だから私は、次のやった:

@deconstructible 
class callable: 
    def __init__(self, foo, *args): 
     self.foo = foo 
     self.args = args 

    def __call__(self): 
     return self.foo(*self.args) 

@deconstructible 
class lazy_call: 
    def __init__(self, foo): 
     self.foo = foo 

    def __call__(self, *args): 
     return callable(self.foo, *args) 

@lazy_call #return this function as callable object that know its arguments 
def get_latest_id(cls, text, *args): 
    try: 
     ret = globals()[cls].objects.latest('id').id + 1 
     return text.format(ret, args) 
    except: 
     return text.format(1, args) 

そして、それは正常に動作しますが、今、私は何のエラーがありません場合、私は何度でもmakemigratonsことができ、それは何も変更が検出されない「言うことはありません(私は無限の移行を持っていることに気づきました)、それは確かに私の機能にリンクしています。それは修正可能ですか?または、私のコードは、ジャンゴの仕組みには有効ではありませんか?

UPD例:

class Article(models.Model): 

    def __str__(self): 
     return self.title 

    title = models.CharField(
     default=get_latest_id('Article', 'Статья #{}'), # <<< THIS ONE 
     help_text='''Название статьи - используется для поиска в Django admin. 
      <br /> # Должно быть уникальным''', 
     max_length=120, 
     unique=True, 
     verbose_name='Именование', 
    ) 
    ... 

私はそれを追加し、各レコードに評価するために関数にOBJECTを渡すために持っているだけでなく、私が作るために他の方法を見ないだって引数を使用したいです関数の普遍的(具体的なクラスだけでなく、具体的なテキストも含む)。

(ジャンゴdoesntの両方を許可する)

そうに機能-デコレータ別名いくつかのシンプルなソリューションを作るために、私は私が欲しいものをラップするためにラムダを使用することはできませんので、私は関数の内部で関数を定義することはできません..私の場合私の最後のものを使用します答えこの関数は、与えられた引数を持つたびに(クラスのinitで一度だけでなく)呼び出されます。

+1

あなたが達成しようとしていることは私には明らかではありません。 – creimers

+0

明確にしたい。 Field.defaultに関するdjangoの文書の一部: フィールドのデフォルト値。これは、値または呼び出し可能なオブジェクトにすることができます。呼び出し可能な場合は、新しいオブジェクトが作成されるたびに呼び出されます。 だから、関数オブジェクトBUTに引数を渡して使いやすくする必要があります。独特の状況のた​​めに私の機能をコピーする必要がありますか?(それはありませんか?) – validname

+0

それはまだ私には分かりません。あなたのモデルのコードを表示できますか? – creimers

答えて

0

私は、単一のクラスに全体これを書き直しました:あまりにも 大規模な単一機能の構文..

@deconstructible 
class get_latest_id(): 
    def __init__(self, cls, text, *args): 
     self.cls = cls 
     self.text = text 
     self.args = args 

    def __call__(self): 
     try: 
      ret = globals()[self.cls].objects.latest('id').id + 1 
      return self.text.format(ret, self.args) 
     except: 
      return self.text.format(1, self.args) 

そして移行は今も元気ですが、私はこのようないけないので、私はからデコレータを作ってみますよこの。

は以下しようとしました:

@deconstructible 
class lazy_call: 
    def __init__(self, foo): 
     self.foo = foo 

    def __call__(self, *args): 
     self.foo.__defaults__ = args 
     self.__call__ = self.foo 

@lazy_call 
def get_latest_id(cls, text, *args): 
    try: 
     latest_id = globals()[self.cls].objects.latest('id').id + 1 
     return self.text.format(latest_id, self.args) 
    except: 
     return self.text.format(1, self.args) 

は怖い見えると私は確かにここで起こっているのか分かりません。それは動作しませんでした(ハ)、エラーは、makemigratonsは大丈夫、二番目の呼び出し(自己 = self.fooを呼び出した後)は起こらない。 Btw私は停止する必要があります。

関連する問題