Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

python - Django save method doesn't work despite successful POST request

I'm using jquery to send request to a Django form. I have this function in views.py:

@csrf_exempt
def update_ops(request):
    print('something something')
    ops_id = request.POST['id']
    instance = Ops.objects.all().filter(id=ops_id)
    form_qdict = QueryDict(request.POST['form_data'])
    form = OpsForm(form_qdict or None, instance=instance)
    if form.is_valid():
        form.save()
        print('saved bro!')
        # return HttpResponseRedirect('/ops/')
    else:
        print('form is not valid')
    return render(request, 'ops_form.html', {'form': form})

urls.py:

urlpatterns = [
url('^update_ops_form/', views.update_ops, name='update_ops_form')
]

the html form in form.html:

 <form action="{% url 'update_ops_form' %}" id="post-form" method="post">
    {% csrf_token %}
 <!--some html form-->
</form>

and the script in form.html:

<script>
    var ops_id = $('#ops_id').text()
    console.log(ops_id)

    $("#post-form").submit(function (event) {
        event.preventDefault(); //prevent default action
        var post_url = $(this).attr("action");
        console.log(post_url)//get form action url
        var request_method = $(this).attr("method"); //get form GET/POST method
        var form_data = $(this).serialize(); //Encode form elements for submission
        console.log(form_data)
        $.ajax({
            url: post_url,
            type: request_method,
            data: {'id':ops_id,'form_data':form_data}
        })
    });
</script>

What I want to do is to update an instance of the Ops Model with form using jquery. The POST request is successful, but it doesn't update the instance that I changed. The only possible reason for the error that I know of is because the url in action parameter of the html form doesn't match the url that maps to the update_ops() function in views.py, but that doesn't seem to be the case here.

Also I'm able to view the Form pre-populated with data from the Model, so I don't think the problem is from declaring those 2. I'm fairly new to Django and Jquery so thank you if you can spend some time and tell me what's wrong.

question from:https://stackoverflow.com/questions/65903729/django-save-method-doesnt-work-despite-successful-post-request

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Assuming OpsForm is a ModelForm and not a Form, I suspect the problem is how you're fetching instance. Currently it's being set to a QuerySet. You want the actual instance:

from django.shortcuts import get_object_or_404
instance = get_object_or_404(Ops, id=ops_id)

If you'd prefer to do your own error handling if the instance doesn't exist then:

instance = Ops.objects.filter(id=ops_id).first()

If it doesn't exist, instance will be set to None.

Edit:

The other thing you should strongly consider doing is to move the id of the Ops instance into the url, then the request body can just be the form and doesn't have to be wrapped in another object. The documentation covers urls pretty well.

This would change your view to:

from django.http.response import HttpResponseForbidden
def update_ops(request, ops_id):
    instance = get_object_or_404(Ops, ops_id)
    if request.method != "POST":
        raise HttpResponseForbidden
    form = OpsForm(request.POST, instance=instance)
    if form.is_valid():
        form.save()
        print('saved bro!')
        return HttpResponseRedirect('/ops/')
    else:
        print('form is not valid')
    return render(request, 'ops_form.html', {'form': form})

urls.py

from django.urls import path
urlpatterns = [
    path('update_ops_form/<int:ops_id>', views.update_ops, name='update_ops_form')
]

template

<form action="{% url 'update_ops_form' ops_id=ops.id %}" id="post-form" method="post">

script:

<script>
    $("#post-form").submit(function (event) {
        event.preventDefault(); //prevent default action
        var post_url = $(this).attr("action");
        console.log(post_url)//get form action url
        var request_method = $(this).attr("method"); //get form GET/POST 
        console.log(form_data)
        $.ajax({
            url: post_url,
            type: request_method,
            data: $(this).serialize()
        })
    });
</script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...