Alex V Alex V - 2 years ago 99
Bash Question

how get django current user's name both in shell and in request

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:


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?

Updates based on comments:

Custom save, assuming one shell user

Yes, I am using a custom save() method.
It looks like:

  • an abstract model class with "general" fields like "modified by" and with a method to update the field; as of the moment it looks like
    modified_by = "unknown user"

  • a real model class takes it as a mixin;

  • and many views and scripts work with the model.

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:

  1. 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.

  2. 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()
>>> users[1].is_authenticated()

So, this easy scenario failed to me...

When custom save() is not enough

Further thought:

  1. Batch model updates triggered in admin app do not use
    , so any custom logic here will not work...

  2. Updating with a Celery task: did not check it yet.

  3. More than one shell user: will have to use a plain old user input to ask for the name and pass to the script?

Any idea to help?

This is how I solved it:

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.created_on =
self.created_by = who
self.modified_on =
self.modified_by = who
self.modified_on =
self.modified_by = who
return super(ModifiedAwareModel, self).save(*args, **kwargs)

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download