2017-03-29 5 views
0

Ich versuche Standardwerte (und andere kwargs) von Modellen Feldern dynamischer zu gestalten, so habe ich eine Funktion dafür:Django Modelle - Passing Funktionsobjekt mit Argumenten

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) 

Ich wollte diese nutzen Funktion als Standard für ein Feld, aber ich brauche Argumente zu sagen, Funktion mit was zu arbeiten. Also habe ich weiter:

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

Und es funktioniert gut, aber jetzt habe ich bemerkt, dass ich unendlich Migrationen haben (wenn es keine Fehler gibt i beliebig oft makemigratons kann und wird es nicht sagen: ‚Keine Änderungen erkannt‘), und es war sicherlich mit meiner Funktion verbunden. Ist es reparierbar? Oder mein Code ist nicht gültig für wie funktioniert Django?

Upd Beispiel:

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='Именование', 
    ) 
    ... 

Ich habe eine Funktion Objekt zu übergeben, um es auf jedem Datensatz zu machen bewerten hinzuzufügen, aber auch ich will Argumente verwenden Coz I andere Art und Weise nicht sehen, machen Funktion universal (nicht nur für konkrete Klasse, mit einigen konkreten Text).

Ich kann nicht Lambda verwenden, etwas zu wickeln ich will, also kann ich nicht definieren Funktionen innerhalb von Funktionen eine einfache Lösung aka Funktion-Dekorateur zu machen (django tut beides ermöglichen)

Also .. Wenn ich verwende meine letzte Antwort Diese Funktion wird jedes Mal (nicht nur einmal bei Init der Klasse) mit gegebenen Argumenten aufgerufen.

+1

Es ist mir nicht ganz klar, was Sie erreichen wollen. – creimers

+0

Wollen klären. Ein Stück von Django Doc über Field.default: Der Standardwert für das Feld. Dies kann ein Wert oder ein aufrufbares Objekt sein. Wenn es aufrufbar ist, wird es jedes Mal aufgerufen, wenn ein neues Objekt erstellt wird. Also ich möchte das Funktionsobjekt ABER mit Argumenten dafür übergeben, um es einfacher zu benutzen. Othrewise krankes Bedürfnis, meine Funktion für irgendeine einzigartige Situation zu kopieren (ist es nicht?) – validname

+0

Es ist mir noch nicht klar. Kannst du den Code deines Modells zeigen? – creimers

Antwort

0

Ich schrieb ganze dies zu einer einzigen Klasse:

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

und Migrationen jetzt in Ordnung ist, aber ich habe wie diese .. Syntax zu massiv für einzelne Funktion, ich werde also versuchen, Dekorateur zu machen aus Dies.

Versuchte folgende:

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

Sieht unheimlich und ich weiß nicht sicher, was hier vor sich geht. Es hat nicht funktioniert (ha), keine Fehler, makemigratons sind in Ordnung, zweiter Anruf (nach Selbst. Anruf = self.foo) nicht passiert. Übrigens muss ich aufhören.