ruo*_*ola 10 python django django-models django-managers
Reading the Django docs, it advices to make a custom creation method for a model named Foo by defining it as create_foo in the manager:
class BookManager(models.Manager):
def create_book(self, title):
book = self.create(title=title)
# do something with the book
return book
class Book(models.Model):
title = models.CharField(max_length=100)
objects = BookManager()
book = Book.objects.create_book("Pride and Prejudice")
Run Code Online (Sandbox Code Playgroud)
My question is that why is the previous one preferred to simply overriding the base class's create method:
class BookManager(models.Manager):
def create(self, title):
book = self.model(title=title)
# do something with the book
book.save()
return book
class Book(models.Model):
title = models.CharField(max_length=100)
objects = BookManager()
book = Book.objects.create("Pride and Prejudice")
Run Code Online (Sandbox Code Playgroud)
Imo it seems that only overriding create will prevent anyone from accidentally using it to make a illformed model instance, since create_foo can always be bypassed completely:
class BookManager(models.Manager):
def create_book(self, title):
book = self.create(title=title, should_not_be_set_manually="critical text")
return book
class Book(models.Model):
title = models.CharField(max_length=100)
should_not_be_set_manually = models.CharField(max_length=100)
objects = BookManager()
# Can make an illformed Book!!
book = Book.objects.create(title="Some title", should_not_be_set_manually="bad value")
Run Code Online (Sandbox Code Playgroud)
Is there any advantage in doing it like the docs suggest, or is actually overriding create just objectively better?
Naf*_*war 11
是的,很明显,你可以做到。但是,如果您仔细观察您从文档中引用的示例,这不是关于您是否应该覆盖 create ,而是关于
但是,如果这样做,请注意不要更改调用签名,因为任何更改都可能会阻止保存模型实例。
保留调用签名。因为可供您使用的接口也可能在 django 内部使用。如果你修改它们,事情可能不会对你造成影响,但对 Django 而言。
在这个例子中,他们建议的不是create模型构造函数,而是模型构造函数。
其次,即使是标准接口 forcreate也只接受关键字参数
def create(self, **kwargs):
Run Code Online (Sandbox Code Playgroud)
但是如果你修改它以接受位置参数,def create(self, title):它会在 Django 内部或以标准方式使用的任何地方中断。所以你应该扩展现有的功能而不是修改并且很可能破坏它。