Home > OS >  Django hidden field value is not in POST data
Django hidden field value is not in POST data

Time:09-16

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">
  • Related