Как получить объект пользователя и передать его в поле формы в django

есть ли лучший способ получить объект пользователя из кода, приведенного ниже в forms.py?

модели

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ...

forms.py

class FooForm(forms.Form):

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("user")
        super(ExperienceStart, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.layout = Layout(InlineRadios('topics'),)

    hardcoded_username = "johndoe" # i want to find a way not to hardcode this

    current_user = User.objects.filter(username=hardcoded_username).first()

    profile = Profile.objects.filter(user=current_user).first()

    ...

    profile_values = list(zip(profile, profile))

    profile = forms.TypedChoiceField(
        label="Select a Profile",
        choices=profile_values,
        coerce=str,
        widget=forms.RadioSelect,
        initial=profile[0],
        required=True)

views.py

def foo(request):
    form = fooForm(request.POST, user=request.user)

    print(form.request) # i have already tried this but i want to get it in form not views

    if request.method == "POST":
        if form.is_valid():
            # do something
    else:
        form = fooForm(user=request.user)

    context = {"form": form}

Я пытаюсь найти способ не вводить имя пользователя в forms.py и получить текущего вошедшего пользователя.

Невключайте его в форму. Формы обычно не знают запросов, и, кроме того, используются для обработки ввода из HTML-формы.

Вы можете использовать параметр формы initial=… для указания начального элемента.

В вашей форме вы можете использовать ModelChoiceField [Django-doc] для выбора Profile элемента:

class FooForm(forms.Form):

    profile = forms.ModelChoiceField(
        label='Select a Profile',
        queryset=Profile.objects.all(),
        widget=forms.RadioSelect,
        required=True
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.layout = Layout(InlineRadios('topics'))

тогда в представлении можно передать профиль пользователя в качестве начального значения:

from django.shortcuts import redirect, render
from django.contrib.auth.decorators import login_required

@login_required
def foo(request):
    if request.method == 'POST':
        form = fooForm(request.POST, initial={'profile': request.user.profile})
        if form.is_valid():
            # do something
            return redirect('name-of-some-view')
    else:
        form = fooForm(initial={'profile': request.user.profile})
    context = {'form': form}
    return render(request, 'some_template.html', context)

Примечание: Вы можете ограничить представления для аутентифицированных пользователей с помощью декоратора @login_required декоратора [Django-doc].


Примечание: В случае успешного POST запроса, вы должны сделать redirect. [Django-doc] для реализации паттерна Post/Redirect/Get [wiki]. Это позволяет избежать повторения POST-запроса, когда пользователь обновляет браузер. браузер.

Вернуться на верх