Автозаполнение формы Django

Есть форма с одним из полей где нужно выбрать свой логин (логины берутся из БД - auth_user.username). Поле логин это ForeignKey.

введите сюда описание изображения

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

models.py:

class Watches_db(models.Model):
...
account = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name='Аккаунт')

forms.py:

class Add_watches_form(forms.ModelForm):
class Meta:
    model = Watches_db
    fields = [..., 'account']
    widgets = {}

views.py:

class AddMyWatches(CreateView):
form_class = Add_watches_form
template_name = 'marketplace/add_product/add_watches.html'

def get_context_data(self, *, object_list=None, **kwargs):
    cont = super().get_context_data(**kwargs)
    cont['title'] = 'Добавьте свой товар'
    return cont

add_watches.html:

<form action = '' method='post' enctype="multipart/form-data">
{% csrf_token %}

{% for wf in form %}
<p><label class='form-label' for='{{wf.id_for_label}}'>{{wf.label}}: </label>{{wf}}</p>
<div class = 'form-error'>{{wf.errors}}</div>
{% endfor %}

<button type="submit">Добавить товар</button>
</form>

Как один из моих идеи это словить request.user.username и сделать return для этого поля. Но понятия не имею как это сделать.


Ответы (1 шт):

Автор решения: Andrey Maslov

Тут есть два варианта

  1. Либо убираем из формы возможность редактировать поле account(исключив его из формы, сделав editable=False), тогда нам нужно будет переопределить метод save в форме, дополнительно заполняя это поле нужным нам значением
  2. Оставляем его в форме, но будем его переопределять в методе clean (можно так же в save). В этом случае нельзя будет отобразить форму в шаблоне, как {{form}}, так как это поле тоже будет отрисовываться.

Дальше, чтобы это поле было доступно в форме, нужно его туда передать (request.user) и форма должна обработать его. Например так:

class AddWatchesForm(forms.ModelForm):

    def __init__(self, user_info, *args, **kwargs):
        self.user_info = user_info
        super().__init__(*args, **kwargs)

    def clean(self):
        """Используем, если не убираем из формы, а просто даем возможность его не вводить blank=True"""
        cleaned_data = super().clean()
        cleaned_data['account'] = self.user_info
        return cleaned_data

    def save(self, *args, **kwargs):
        """Переопределим метод save, если используем вариант, когда исключаем account из формы"""
        self.instance.account = self.user_info
        return super().save(*args, **kwargs)

    class Meta:
        ...

Для того, чтобы передать пользователя в форму, переопределим метод get_form_kwargs у нашего CreateView

    def get_form_kwargs(self):
        """Необходимо учитывать, что текущий пользователь у нас может быть не залогинен."""
        kwargs = super().get_form_kwargs()
        kwargs.update({
            'user_info': self.request.user if self.request.user.is_authenticated else None,
        })
        return kwargs

Так же, рекомендую придерживаться Pep8 при выборе имен для классов

→ Ссылка