#django #django-models
#django #django-модели
Вопрос:
Я просто хочу знать, откуда берется метод create в django.
Я проверил класс модели, класс BaseManager и так далее.
Я не могу найти, где определен метод create.
Кто-нибудь знает об этом?
https://github.com/django/django/blob/2d6179c819010f6a9d00835d5893c4593c0b85a0/django/
Ответ №1:
Короткий ответ: В QuerySet
классе.
Это определено в разделе QuerySet
. Действительно, в Manager
, он переносится в QuerySet
исходный код [GitHub]:
@classmethod
def _get_queryset_methods(cls, queryset_class):
def create_method(name, method):
def manager_method(self, *args, **kwargs):
return getattr(self.get_queryset(), name)(*args, **kwargs)
manager_method.__name__ = method.__name__
manager_method.__doc__ = method.__doc__
return manager_method
new_methods = {}
for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction):
# Only copy missing methods.
if hasattr(cls, name):
continue
# Only copy public methods or methods with the attribute `queryset_only=False`.
queryset_only = getattr(method, 'queryset_only', None)
if queryset_only or (queryset_only is None and name.startswith('_')):
continue
# Copy the method onto the manager.
new_methods[name] = create_method(name, method)
return new_methods
_get_queryset_methods
Вызывается при построении Manager
класса [GitHub]:
class Manager(BaseManager.from_queryset(QuerySet)): pass
и from_queryset
присоединит QuerySet
методы к Manager
классу [GitHub]:
@classmethod
def from_queryset(cls, queryset_class, class_name=None):
if class_name is None:
class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__)
return type(class_name, (cls,), {
'_queryset_class': queryset_class,
**cls._get_queryset_methods(queryset_class),
})
Это делается для реализации для каждого метода в QuerySet
методе a в Manager
, чтобы предотвратить многократную реализацию одной и той же логики. Если вы таким образом вызовете .create
.objects
менеджера (или любого другого менеджера), он вызовет .get_queryset()
, а затем вызовет этот метод (здесь create
) для данного QuerySet
, который get_queryset
возвращает.
Таким QuerySet
образом, есть метод create
, который реализован как [GitHub]:
def create(self, **kwargs):
"""
Create a new object with the given kwargs, saving it to the database
and returning the created object.
"""
obj = self.model(**kwargs)
self._for_write = True
obj.save(force_insert=True, using=self.db)
return obj