'How can i submit a form with logged in user as default?
After you sign up, you are prompted to the login page, and after you login, you are redirected to another page that contains a form used for gathering additional information about the new user. The problem is that the form doesn't submit if i don't specify the {{form.user}} instance in the html file. Probably because the user_id is not recognized by default. When i specify it, the form let me chooses from already existing users, and i would like it to go with the logged in user by default.
models
class AdditionalInfoModel(models.Model):
objects = None
skill_choices = (('Beginner', 'BEGINNER'),
('Intermediate', 'INTERMEDIATE'),
('Expert', 'EXPERT'))
user = models.OneToOneField(User, on_delete=models.CASCADE)
location = models.CharField(max_length=30, blank=True)
assumed_technical_ski_level = models.CharField(max_length=30, choices=skill_choices)
years_of_experience = models.PositiveIntegerField(blank=True)
money_to_spend = models.PositiveIntegerField(blank=True)
def __str__(self):
return self.user.username
views
class CreateInfoView(LoginRequiredMixin, CreateView):
model = AdditionalInfoModel
form_class = AdditionallnfoModelForm
template_name = "user_ski_experience/additional_info.html"
def get_form_kwargs(self):
variable_to_send = super(CreateInfoView,
self).get_form_kwargs()
variable_to_send.update({'pk': None})
return variable_to_send
def get_success_url(self):
return reverse('aplicatie2:home')
forms
class AdditionallnfoModelForm(forms.ModelForm):
class Meta:
model = AdditionalInfoModel
fields = '__all__'
def __init__(self, pk, *args, **kwargs):
super(AdditionallnfoModelForm, self).__init__(*args,
**kwargs)
self.pk = pk
def clean(self):
return self.cleaned_data
html
{% load crispy_forms_tags %}
{% block content %}
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
<h1> Let's get started with some questions ! </h1>
<h2> This will help us get to know your ski experience
</h2>
<li> Your user name is: {{form.user|as_crispy_field}}</li>
<li> Where do you live ?
{{form.location|as_crispy_field}} </li>
<li> How would you rank yourself as a skier ?
{{form.assumed_technical_ski_level|as_crispy_field}}
</li>
<li> How many years of ski experience do you have ?
{{form.years_of_experience|as_crispy_field}} </li>
<li> How much ar you willing to spend ?
{{form.money_to_spend|as_crispy_field}} </li>
<button type="submit" onclick = "{% url 'aplicatie2:home'
%}">Submit</button>
</form>
</body>
{% endblock %}
the log in and sign up are done using standard django models
Solution 1:[1]
I suggest using a disabled field and setting the initial value of the user through the initializer method of the form. The disabled fields are completely ignored in the POST requests so user will not be able to change the default user you set through that field.
Django docs on the disabled attribute: https://docs.djangoproject.com/en/4.0/ref/forms/fields/#disabled
views.py
class CreateInfoView(LoginRequiredMixin, CreateView):
model = AdditionalInfoModel
form_class = AdditionallnfoModelForm
template_name = "user_ski_experience/additional_info.html"
def get_form_kwargs(self):
variable_to_send = super(CreateInfoView,
self).get_form_kwargs()
variable_to_send.update({'pk': None})
variable_to_send.update({'pk_user': self.request.user.pk})
return variable_to_send
def get_success_url(self):
return reverse('aplicatie2:home')
forms.py
class AdditionallnfoModelForm(forms.ModelForm):
class Meta:
model = AdditionalInfoModel
fields = '__all__'
def __init__(self, pk, *args, **kwargs):
pk_user = kwargs.pop('pk_user')
super(AdditionallnfoModelForm, self).__init__(*args,
**kwargs)
self.pk = pk
# Make the user field readonly
self.fields['user'].disabled = True
self.fields['user'].initial = pk_user
def clean(self):
return self.cleaned_data
EDIT: also found issues in your HTML. The form won't submit because your HTML is not correct for form submitting. Something like below should work:
{% load crispy_forms_tags %}
{% block content %}
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- Place the POST endpoint URL in the action attribute of the 'form' tag -->
<form method="post" action="{% url 'aplicatie2:home' %}">
{% csrf_token %}
<h1> Let's get started with some questions ! </h1>
<h2> This will help us get to know your ski experience
</h2>
<li> Your user name is: {{form.user|as_crispy_field}}</li>
<li> Where do you live ?
{{form.location|as_crispy_field}} </li>
<li> How would you rank yourself as a skier ?
{{form.assumed_technical_ski_level|as_crispy_field}}
</li>
<li> How many years of ski experience do you have ?
{{form.years_of_experience|as_crispy_field}} </li>
<li> How much ar you willing to spend ?
{{form.money_to_spend|as_crispy_field}} </li>
<!-- You can't use <button> element for submitting a form without special JS -->
<input type="submit">Submit</button>
</form>
</body>
{% endblock %}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |