Reputation: 63
I have to update a "modified by" field in models with current user's name. It's very easy to get username in views with request like this:
request.user.username
However, when an model's instance is modified using shell (I have scripts to batch update and process entries) there's no request.
What would be a good way to get current user's name both from request (if any) and from shell process?
Yes, I am using a custom save() method. It looks like:
modified_by = "unknown user"
;So, I know how to manually assign a value to the field. The problem is to how to know if a particular transaction was done with or without a request, and if without request (shell), then which admin/user done it.
What I tried:
Passing request as a required parameter from any view to the abstract models, method: it did not work (at least, I do not know how to safely code a required parameter to and abstract model's method as opposed to a plain function in a view); also, I do not know how to pass request when calling the same method from shell.
In shell, I easily got User.objects.all() and tried to check: if user is authenticated, then use his/her username, else assume it's a shell user and manually assign "shell user" value to "modified by".
To my surprise, any returned user is authenticated in shell:
>>> users = User.objects.all()
>>> users
[<User: teddy>, <User: alexander>]
>>> users[0].is_authenticated()
True
>>> users[1].is_authenticated()
True
>>>
So, this easy scenario failed to me...
Further thought:
save()
, so any custom logic here will not work...Any idea to help?
An abstract-class model with a parameter (who) to be manually assigned when saving a model.
class ModifiedAwareModel(models.Model):
"""
ABC to keep track of when and by whom a model was created and updated.
"""
created_on = models.DateTimeField(_('created on'), blank=True, editable=False)
created_by = models.CharField(_('created by'), max_length=100, blank=True, editable=False)
modified_on = models.DateTimeField(_('modified on'), blank=True, editable=False)
modified_by = models.CharField(_('modified by'), max_length=100, blank=True, editable=False)
class Meta:
abstract = True
def save(self, who="Django", *args, **kwargs):
if not self.pk:
self.created_on = timezone.now()
self.created_by = who
self.modified_on = timezone.now()
self.modified_by = who
else:
self.modified_on = timezone.now()
self.modified_by = who
return super(ModifiedAwareModel, self).save(*args, **kwargs)
Upvotes: 0
Views: 4106
Reputation: 1691
When using the Django shell
, there is no current User
. A method of working around this would be get the person who is using the shell to assign a User
to the modified by
field manually. This User
would probably be dedicated for shell operations, but it doesn't have to be that way. Another option could be to write a custom save()
function for the model if you will only be changing it through the shell.
Upvotes: 1