I need to send form data via POST request to save a new model instance to DB. I have a hidden field name="owner" in html which has a value of authorized user id. I can see this value in HTML code, but not in POST request.
This gives me Chrome Devtools:
<input type="hidden" id="owner" name="owner" value="3">
And this gives me a pyCharm's debugger:
cleaned_data = {'latitude': 55.2288, 'longitude': 24.3686, 'comment': '', 'category': <Category: Host>}
What is the problem?
I have this code in Django views.py:
if request.method == "POST":
form = AddMarkerForm(request.POST)
if form.is_valid():
form.save()
messages.success(
request, _("Marker added successfully!"), extra_tags="success"
)
return redirect(to="home")
else:
messages.error(request, _("Error. Check coordinates."), extra_tags="danger")
else:
form = AddMarkerForm()
And html:
<form method="post" enctype="multipart/form-data"
id="addMarkerForm" name="addMarkerForm">
{% csrf_token %}
{% for field in form.visible_fields|slice:":2" %}
<div >
{{ field }}
</div>
{% endfor %}
{% for field in form.visible_fields|slice:"2:" %}
<div >
{{ field }}
</div>
{% endfor %}
<input type="hidden" id="owner" name="owner"
value="{% if request.user %}{{ request.user.id }}{% endif %}">
<div >
<button type="button"
data-bs-dismiss="modal">{% translate "Close" %}</button>
<button type="submit" name="submit" >{% translate "Add" %}</button>
</div>
</form>
A form code in forms.py:
class AddMarkerForm(forms.ModelForm):
"""Form for adding a new marker on a frontend."""
latitude = forms.FloatField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"id": "latitude",
"placeholder": _("Latitude"),
}
),
)
longitude = forms.FloatField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"id": "longitude",
"placeholder": _("Longitude"),
}
)
)
category = forms.ModelChoiceField(
queryset=Category.objects.all(),
empty_label=_("Choose category"),
widget=forms.Select(attrs={"class": "form-select"}),
)
class Meta:
model = Marker
fields = ["latitude", "longitude", "comment", "category"]
widgets = {
"comment": forms.Textarea(
attrs={
"class": "form-control",
"rows": 3,
"max-length": 200,
"placeholder": _("Comment, not required"),
}
),
}
CodePudding user response:
I think that the submitted form does contain the owner
data, but that the problem is elsewhere: there isn't any field owner
in your AddMarkerForm
.
First of all, check that request.POST
does contain "owner": "3"
in your IDE or terminal by simply printing it for instance.
Then, you'll probably have to add a field owner
to your AddMarkerForm
. See this other Stackoverflow question or this page of the Django documentation if you need more help.
CodePudding user response:
You have to add this field in your form for retrieve it in the cleaned_data of the form:
fields = ["latitude", "longitude", "comment", "category", "owner"]
or if this field does not exist in your model, you have to define a field in form class:
owner = forms.ModelChoiceField(queryset=get_user_model().objects.all())
Your form remove data which not match with defines fields. I think you can show your hidden field when you print request.POST before create your form object.
PS: @Scūriolus got ahead of me for the answer
CodePudding user response:
So, none of the answers above worked for me. I've handled the issue with this code:
if request.method == "POST":
form = AddMarkerForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.owner = request.user
form.save()
And in HTML template I might to delete field:
<input type="hidden" id="owner" name="owner" value="{% if request.user %}{{ request.user.id }}{% endif %}">
Now it works.
CodePudding user response:
You can change the type to text and hide it with CSS:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
}
<input type="text" id="owner" name="owner" value="3">