What is the difference between creating a user object instance using a class instantiation operator and using the model’s manager create() function?
Why would a User instance be instantiated using an operator instead of
What are the advantages to instantiating a user object instance this way?
The allauth django package has a function
allauth.account.adapter.new_user() that returns
I was not familiar with this set of double parens, but apparently this is just a compact way to place a normal “class instantiation operator.”
get_user_model() returns the user model class.
I believe the second set of parens acts similar to if you imported the User model and then did:
user = User(). This apparently creates a new instance of the class.
I would normally “create” a new user object instance using some variation off
The reason this is causing me some concerns is that I had overridden the User model’s create() in a custom manager. But this class instantiation operator seems to possibly sidestep my custom manager’s custom create method.
User.objects.create() creates an instance of User and commits that instance to the database.
a_user = User()
a_user = get_user_model()()
user_class = get_user_model()
a_user = user_class()
All create an instance of User, but does not write that instance to the database. At some point you would need to do something like
a_user.save() to save the instance to the database.
See the docs for
Thank you, Ken.
Can you or anyone else suggest a best practice for reliably hooking into a post_create event on my custom User model?
It seems I can not count on catching it with a custom manager overriding
create(), or with a post_create signal if the user is created using the way you outlined.
I could try for testing
if [self.pk](http://self.pk) is None: in an overridden
save() method on the model class, but that would be missed by a
From our perspective, the “best practice” for using signals is to not use signals. You’ve identified some of the holes in them already. I don’t believe they’re worth the trouble.
I’ve been working with Django seriously now for 8 years, and have never written a signal that has gone into a production system.
That’s not to say that they’re not useful, just that I believe the range of situations where they are useful is a lot smaller than it appears they might (or should) be.
Thanks for that additional feedback. I’m also not a fan of signals, they seem a bit like insta-spaghetti.
Can you suggest techniques to use in lieu of signals to reliably execute code after a User object instance is created.
For example, monitoring
if self.pk is None: in
save() and carefully documenting / writing extra behavior for code that calls
The only sure way of executing code on a create is a database trigger.
Since bulk_create is a method on the manager, you could try overriding it in a custom manager.
def bulk_create(self, objs, batch_size=None, ignore_conflicts=False):
new_rows = super().bulk_create(objs, batch_size, ignore_conflicts)
for row in new_rows:
# Do something with each new instance
(Winging this. No idea how well this would work. If this causes your computer to melt or all your data to be randomized, don’t blame me.)
Thanks for this and the prior feedback, Ken.