Reputation: 19150
I'm using Django with Python 3.7 and PyCharm. I'm following this tutorial for learning how to create model and save them into the database -- https://docs.djangoproject.com/en/dev/topics/db/queries/#creating-objects . The tutorial refers to manager for retrieving objects, but not for setting them, so I'm confused as to why I get the below error
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'
when I'm trying to create and save an object. Below is how I define my object in my models.py file ...
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
I'm sure I'm missing something really obvious, but I don't know what it is.
Edit: Many have suggested using the "Article.objects.create" method but below is the output from the console ...
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
Upvotes: 1
Views: 1236
Reputation: 411
To create an article in database use manager's create method (params should be named, not positioned, as in your example)
Article.objects.create(mainpage=mainpage, path=path, url=url,
votes=votes, comments=comments)
or you can initialise class instance and then save it. Here params could be positioned or named, no matter.
article = Article(mainpage, path, url, votes, comments)
article.save()
Your method def create(cls, mainpage, path, url, votes, comments):
makes no sense, because it duplicates call (__call__
method) of a class, like in my second example. If you want to add some extra logic to object creation, you should define custom Manager
class and add method there and then link your model's objects property to you custom manager class like objects = CustomManager()
Upvotes: 1
Reputation: 8026
When you define a Model Class, Django jumps into the fray and adds a default Manager to your model under the "objects" property. You can customize the Model and the Manager for different purposes.
Generally methods on your Model should deal with a single instance, or conceptually a row in your database. Model.save()
, Model.delete()
all act on a single instance or row.
Methods on your manager should usually work with your table as a whole, such as filter()
, get()
, aggregate()
, because these functions perform operations against your table. You also have the create()
method on your manager because it adds a row to your table. Further, you can define custom Manager's and assign them to different properties on your model. For example:
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
Now to your problem, Article.objects.create_article(...)
does not seem to exist, you should probably use Article.objects.create(...)
because the default Manager does have a create()
method.
Using Article.objects.create(...)
will persist a new Article to the database and return it. Otherwise, you could technically use your Article.create(...)
method to create an in-memory instance of Article, however it has not been saved to the database so keep in mind you will have to call save()
on the instance before it's persisted to your database.
https://docs.djangoproject.com/en/2.1/topics/db/models/ https://docs.djangoproject.com/en/2.1/topics/db/managers/
Upvotes: 2