Erstens, warum init 3 mal ausgeführt wird?
Obwohl die models.py
nur einmal importiert, die Field
Objekte erstellt darin, wie ...
myfield = MyMixinCharField(max_length=512, new_arg="myarg")
... mehrfach geklont, was beinhaltet das Feld Konstruktor aufrufen das Schlüsselwort args mit Sie wurden ursprünglich mit erstellt. Sie können die traceback
Modul zu sehen, benutzen, wo es passiert ...
import traceback
class MyMixin(object):
def __init__(self, new_arg=None, *args, **kwargs):
super(MyMixin, self).__init__(*args, **kwargs)
print self.__class__, new_arg
traceback.print_stack()
..., die die folgenden mehrmals in der Ausgabe zeigt, ...
File "django/db/migrations/state.py", line 393, in from_model
fields.append((name, field.clone()))
File "django/db/models/fields/__init__.py", line 464, in clone
return self.__class__(*args, **kwargs)
File "myproj/myapp/models.py", line 11, in __init__
traceback.print_stack()
Wo liegt der Kwarg 'New_arg' in den zweiten beiden?
Wenn Sie ursprünglich ... genannt als new_arg
Parameter übergeben zu ...
def __init__(self, new_arg=None, *args, **kwargs):
... sondern weil Sie
myfield = MyMixinCharField(max_length=512, new_arg="myarg")
... "myarg"
wird don Übergeben Sie diesen Parameter nicht an den zugrunde liegenden Field
Konstruktor ...
super(MyMixin, self).__init__(*args, **kwargs)
...Es wird nicht irgendwo im zugrunde liegenden Field
-Objekt gespeichert. Wenn das Feld geklont wird, wird der Parameter new_arg
nicht an den Konstruktor übergeben.
jedoch zum Oberklassenkonstruktors diese Option geben wird nicht funktionieren, weil die CharField
nicht, dass Schlüsselwort arg unterstützen, so dass Sie bekommen ...
File "myproj/myapp/models.py", line 29, in MyMixinModelTest
myfield = MyMixinCharField(max_length=512, new_arg="myarg")
File "myproj/myapp/models.py", line 25, in __init__
super(MyMixinCharField, self).__init__(*args, **kwargs)
File "django/db/models/fields/__init__.py", line 1072, in __init__
super(CharField, self).__init__(*args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'new_arg'
Wie erstelle ich ein Feld Mixin für Django?
Aufgrund dieses Klonen Verhalten, wenn Sie benutzerdefinierte Feld Optionen hinzufügen möchten, müssen Sie eine benutzerdefinierte deconstruct()
Methode definieren, so dass Django Ihre neue Option ...
class MyMixin(object):
def __init__(self, new_arg=None, *args, **kwargs):
super(MyMixin, self).__init__(*args, **kwargs)
self.new_arg = new_arg
print self.__class__, new_arg
def deconstruct(self):
name, path, args, kwargs = super(MyMixin, self).deconstruct()
kwargs['new_arg'] = self.new_arg
return name, path, args, kwargs
class MyMixinCharField(MyMixin, models.CharField):
pass
class MyMixinModelTest(models.Model):
myfield = MyMixinCharField(max_length=512, new_arg="myarg")
Serialisierung kann ... welche Ausgänge ...
<class 'myapp.models.MyMixinCharField'> myarg
<class 'myapp.models.MyMixinCharField'> myarg
<class 'myapp.models.MyMixinCharField'> myarg
Welche Version von Django verwenden Sie? – Aya
Ich benutze Version 1.9 – jmerkow
@solarissmoke es ist nicht die gleiche Frage. –