Нужен ли мне менеджер при создании и сохранении объектов в Django? - PullRequest
0 голосов
/ 09 января 2019

Я использую Django с Python 3.7 и PyCharm. Я изучаю этот урок, чтобы научиться создавать модели и сохранять их в базе данных - https://docs.djangoproject.com/en/dev/topics/db/queries/#creating-objects. Учебник относится к менеджеру для получения объектов, но не для их установки, поэтому я не понимаю, почему я получаю ошибку ниже

Article.objects.create_article(main page, '/path', 'url', 10, 22)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'Manager' object has no attribute 'create_article'

когда я пытаюсь создать и сохранить объект. Ниже описано, как я определяю свой объект в моем файле models.py ...

class Article(models.Model):
    mainpage = models.ForeignKey(MainPage, on_delete=models.CASCADE,)
    path = models.CharField(max_length=100)
    url = models.TextField
    time = models.DateTimeField(default=datetime.now)
    votes = models.IntegerField(default=0)
    comments = models.IntegerField(default=0)

    def __str__(self):
        return self.path

    @classmethod
    def create(cls, mainpage, path, url, votes, comments):
        article = cls(mainpage=mainpage,path=path,url=url,votes=votes,comments=comments)
        return article

Я уверен, что упускаю что-то действительно очевидное, но я не знаю, что это такое.

Редактировать: Многие предлагали использовать метод Article.objects.create, но ниже приведен вывод из консоли ...

Article.objects.create(mainpage=mainpage, path='/path', url='url', votes=10, comments=22)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/davea/Documents/workspace/mainarticles_project/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/davea/Documents/workspace/mainarticles_project/venv/lib/python3.7/site-packages/django/db/models/query.py", line 411, in create
    obj = self.model(**kwargs)
  File "/Users/davea/Documents/workspace/mainarticles_project/venv/lib/python3.7/site-packages/django/db/models/base.py", line 485, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % kwarg)
TypeError: 'url' is an invalid keyword argument for this function

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Чтобы создать статью в базе данных, используйте метод create менеджера (параметры должны быть названы, а не расположены, как в вашем примере)

Article.objects.create(mainpage=mainpage, path=path, url=url, 
                       votes=votes, comments=comments)

или вы можете инициализировать экземпляр класса, а затем сохранить его. Здесь параметры могут быть расположены или названы, независимо от того,

article = Article(mainpage, path, url, votes, comments)
article.save()

Ваш метод def create(cls, mainpage, path, url, votes, comments): не имеет смысла, потому что он дублирует вызов (__call__ метод) класса, как в моем втором примере. Если вы хотите добавить дополнительную логику к созданию объекта, вы должны определить собственный класс Manager и добавить туда метод, а затем связать свойство объектов вашей модели с вашим собственным классом менеджера, таким как objects = CustomManager()

0 голосов
/ 09 января 2019

Когда вы определяете класс модели, Django вступает в схватку и добавляет в вашу модель Manager по умолчанию в свойстве «objects». Вы можете настроить Модель и Диспетчер для различных целей.

Как правило, методы вашей Модели должны иметь дело с одним экземпляром или концептуально строкой в ​​вашей базе данных. Model.save(), Model.delete() все действуют на один экземпляр или строку.

Методы вашего менеджера обычно должны работать с вашей таблицей в целом, например filter(), get(), aggregate(), потому что эти функции выполняют операции с вашей таблицей. У вас также есть метод create() в вашем менеджере, потому что он добавляет строку в вашу таблицу. Кроме того, вы можете определить собственные менеджеры и назначить их различным свойствам вашей модели. Например:

class EngineerManager(Manager):
    def get_queryset(self):
        return super().get_queryset().filter(employee_type="engineer")

class ManagerManager(Manager):
    def get_queryset(self):
        return super().get_queryset().filter(employee_type="manager")

class Employee(Model):
    employee_type = models.CharField()

    engineers = EngineerManager()
    managers = ManagerManager()
    objects = Manager()  # This is always added to your models to list all objects

Employee.engineers.filter()  # Will only return engineering employees
Employee.objects.filter()  # Will return ALL employees

Теперь к вашей проблеме Article.objects.create_article(...), похоже, не существует, вам, вероятно, следует использовать Article.objects.create(...), потому что в менеджере по умолчанию есть метод create().

Использование Article.objects.create(...) сохранит новую статью в базе данных и вернет ее. В противном случае вы могли бы технически использовать метод Article.create(...) для создания экземпляра Article в памяти, однако он не был сохранен в базе данных, поэтому имейте в виду, что вам придется вызывать save() для экземпляра, прежде чем он будет сохранен в вашем базы данных.

https://docs.djangoproject.com/en/2.1/topics/db/models/ https://docs.djangoproject.com/en/2.1/topics/db/managers/

...