Как получить объект пользователя и передать его в поле формы в 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-запроса, когда пользователь обновляет браузер. браузер.