как получить имя текущего пользователя django в оболочке и в запросе

Я должен обновить поле «modified by» в моделях с именем текущего пользователя.
Это очень легко получить имя пользователя в представлениях с запросом, как это:

запрос.пользователь.имя пользователя:

Однако при изменении экземпляра модели с помощью оболочки (у меня есть скрипты для пакетного обновления и обработки записей) запроса нет.

Как получить имя текущего пользователя как из запроса (если есть), так и из процесса shell?

Обновления на основе комментариев:

Пользовательское сохранение, предполагающее одного пользователя оболочки

Да, я использую пользовательский метод save ().
Это выглядит как:

  • абстрактный класс модели с» общими «полями, такими как» modified by » и с методом обновления поля; на данный момент он выглядит как modified_by = "unknown user";
  • реальный класс модели принимает его как mixin;
  • и многие представления и сценарии работают с моделью.

Таким образом, я знаю, как вручную назначить значение полю.
Проблема заключается в том, как узнать, была ли определенная транзакция выполнена с или без запроса, и если без запроса (shell), то какой администратор/пользователь сделал это.

Что я пытался:

  1. Передача запроса как необходимого параметра из любого представления в абстрактные модели, метод: он не работал (по крайней мере, я не знаю, как безопасно кодировать требуемый параметр и метод абстрактной модели в отличие от простой функции в представлении); также я не знаю, как передать запрос при вызове того же метода из оболочки.

  2. В оболочке, я легко получил пользователя.объекты.all () и попытался проверить: если пользователь аутентифицируется, то используйте его/ее имя пользователя, иначе предположите, что это пользователь оболочки и вручную назначьте значение «пользователь оболочки» «изменено».

К моему удивлению, любой возвращенный пользователь аутентифицируется в shell:

>>> users = User.objects.all()
>>> users
[<User: teddy>, <User: alexander>]
>>> users[0].is_authenticated()
True
>>> users[1].is_authenticated()
True
>>>

Итак, этот простой сценарий не удался мне…

Когда пользовательское сохранение() недостаточно

Дальнейшая мысль:

  1. Обновления пакетной модели, запускаемые в admin app, не используютсяsave(), поэтому любая пользовательская логика здесь не будет работать…
  2. Обновление с задачей сельдерея: еще не проверил.
  3. Более одного пользователя оболочки: придется использовать обычный старый пользовательский ввод, чтобы запросить имя и перейти к скрипту?

Есть идея помочь?

Вот как я решил это:

Модель абстрактного класса с параметром (who), назначаемым вручную при сохранении модели.

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)

1 ответ

  1. При использовании Django shellнет тока User. Способ обойти это было бы получить человека, который использует оболочку, чтобы назначить Usermodified byполе вручную. ЭтоUser, вероятно, будет выделено для операций shell, но это не должно быть так. Другой вариант-написать пользовательскую save()функцию для модели, если вы будете изменять ее только через оболочку.