Как назначить зарегистрированного пользователя в качестве значения по умолчанию для поля модели?

Я хотел бы сделать что-то вроде этого:

class Task(models.Model):
    ...
    created_by = models.ForeignKey(User, **default=[LoggedInUser]** blank=True, null=True, related_name='created_by')

Возможно ли это? Я не мог найти, какой правильный способ получить зарегистрированного пользователя, помимо выполнения request.user, в представлении, которое, похоже, не работает здесь.

PS_ Я понимаю, что могу инициализировать данные модели другими способами, но я думаю, что это самый чистый способ.

Ответ 1

Нет, вы не можете сделать это так. Django (и Python) имеет в значительной степени нулевые глобальные значения и что Good Thing (tm). Обычно вы получаете текущего пользователя в view(request) с request.user. Затем вы можете передать это как параметр для различных методов/функций, но попытка установить глобальный user приведет только к разрывам в многопоточной среде.

Должна быть наклейка на бампер, которая гласит: "Глобалы - зло". Это даст вам хорошее представление о моей проблеме номер один с PHP.

Ответ 2

Если вы хотите достичь этого в интерфейсе администратора, вы можете использовать метод save_model. Ниже приведен пример:

class List(models.Model):
    title = models.CharField(max_length=64)
    author = models.ForeignKey(User)

class ListAdmin(admin.ModelAdmin):
    fields = ('title',)
    def save_model(self, request, obj, form, change):
        obj.author = request.user
        obj.save()

Ответ 3

РЕШИТЬ: Я буду использовать пример, но важная часть - это функция на views.py. Пользователь автоматически доступен для Django. Обратите внимание, что поле модели 'autor' имеет ForeignKey для 'User'. В 'def form_valid' ниже я назначаю текущего пользователя, который вошел в систему, как значение по умолчанию.

Если это ваша модель:

class ProspectoAccion(models.Model):
"""
Model representing a comment against a blog post.
"""
    descripcion = models.TextField(max_length=1000)
    autor = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    accion_date = models.DateTimeField(auto_now_add=True)
    prospecto= models.ForeignKey(Prospecto, on_delete=models.CASCADE)
    tipo_accion = models.ForeignKey('Accion', on_delete=models.SET_NULL, null=True)

И у вас есть представление на основе классов, выполните следующие действия:

class ProspectoAccionCreate(LoginRequiredMixin, CreateView):
"""
Form for adding una acción. Requires login (despues poner)
"""
    model = ProspectoAccion
    fields = ['tipo_accion','descripcion',]

    def form_valid(self, form):

        #Add logged-in user as autor of comment THIS IS THE KEY TO THE SOLUTION
        form.instance.autor = self.request.user

        # Call super-class form validation behaviour
        return super(ProspectoAccionCreate, self).form_valid(form)

ЗДЕСЬ ПРИМЕР ИЗ ДОКУМЕНТАЦИИ:https://docs.djangoproject.com/en/2.0/topics/class-based-views/generic-editing/#models-and-request-user

Ответ 4

Если используется ModelForm, следующее значение будет заполняться по умолчанию для специального поля. например, владелец зарегистрирован как charfield для имени пользователя

def fillview(request):
    instance = YourModel(owner=request.user.username)
    form = YourModelForm(instance=instance)

    if request.method == 'POST':
        form = YourModelForm(request.POST, request.FILES)
        if form.is_valid():
            pass
            return render(request, 'success.html')

    return render(request, 'fill.html', {'form': form})

При входе в систему вы можете увидеть, что владельцем зарегистрировано текущее имя пользователя.

Ответ 5

По умолчанию, Django уже создает атрибут "creation_by". Вам не нужно создавать свои собственные.

Если вам, тем не менее, необходимо сохранить эту информацию отдельно, скажем, чтобы иметь возможность изменить пользователя позже, не затрагивая первоначальное значение создателя, тогда вы можете переопределить функцию сохранения, чтобы получить значение, которое Django по умолчанию присваивает "create_user" :

class Application(models.Model):
    property = models.ForeignKey(Property, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='applications', editable=False, null=True)
    ...

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if not self.user:
            self.user = self.created_by
            super(Application, self).save(*args, **kwargs)