Reputation: 125
is there a better way to get the user object from the code below in forms.py
?
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
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)
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}
I am trying to find a way not to hardcode the username in forms.py
and get the current logged in user.
Upvotes: 2
Views: 1830
Reputation: 477704
Don't include it in the form. Forms are typically request unaware, and furthermore are used to process input from the HTML form.
You can make use of the initial=…
parameter of the form to specify the initial item.
In your form you can use a ModelChoiceField
[Django-doc] to select a Profile
item:
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'))
then in the view, you can pass the profile of the user as initial value:
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)
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
Note: In case of a successful POST request, you should make a
redirect
[Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.
Upvotes: 1