添加新对象到列表中而不使用 Django 和 Ajax 刷新



我正在寻找一位在使用JS、Ajax和jquery的Django项目中帮助我的人。我正在尝试创建一些东西,比如在django管理页面上添加对象。我曾经https://www.pluralsight.com/guides/work-with-ajax-django,几乎一切都很好,但是。。。在我的表单上,我有一个带有作者的多选字段,当我按下按钮添加新作者时,对象正确地保存在DB中,但在表单中,我看不到新对象。当我重新加载页面时,新对象在这个多选字段中。

我想我应该刷新字段以在列表中看到一个新对象,但我不知道这是实现这个目标的正确方法。

[编辑]

型号.py

class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
book_author = models.ManyToManyField(Author,blank=True,)
...

表单.py

class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name', ]
widgets = {
'name': forms.TextInput(),
}

views.py我添加了SaveAutor类

def author_add_view(request):
form = AuthorForm()
return render(request,
"author/custom_create_author.html",
{"form": form})
class SaveAuthor(View):
template_name = "author/custom_create_author.html"
def get(self, request):
author_form = AuthorForm(request)
return render(request,
self.template_name,
{'form': author_form})
def post(self, request):
#assume authorForm has author_name defined
author_form = AuthorForm(data=request.POST)
if author_form.is_valid():
author = Author() #here is class name or form name? 
author.name = author_form.cleaned_data['name']
author.save()
return JsonResponse({'author_id':  author.id,
'author_name': author.name})
# error response or whatever you want to return
return JsonResponse({'error':  'author form is not valid'})

我在urls.py中注册了这些视图

urls.py

# add an author
path('author/add/', views.author_add_view, 
name='author_add'),
# not sure if I should add as_view() at the end
path('author/new-add/', views.SaveAuthor.as_view(), 
name='new_author_add'),

当我尝试使用SaveAuthor基于类的视图检查带有表单的页面是否正确显示时,我会出现错误'WSGIRequest'对象没有属性'get',但当我使用author_add_view时,我得到了模板。

custom_create_author.html

$("#author-form").submit(function (e) {
// preventing from page reload and default actions
e.preventDefault();
// serialize the data for sending the form data.
var serializedData = $(this).serialize();
// make POST ajax call
$.ajax({
type: 'POST',
url: "{% url '.' %}", //serializer_ajax_mehit_from_vies
data: serializedData,
success: function (response) {
// on successfull creating object
// 1. clear the form.
$("#author-form").trigger('reset');
// 2. focus to nickname input
$("#id_author_name").focus();
},
error: function (response) {
// alert the error if any error occured
alert(response["responseJSON"]["error"]);
}
})
})
{% load static %}
{% load widget_tweaks %}
{% block content %}
<h4>
My author
</h4>
<form id="author-form">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<button class="btn btn-outline-success" type="submit">save</button>
</form>
<br>
{% endblock %}

这是另一个页面,我试图将这本书与多选字段作者联系起来(这是典型的表单,但我只附上了弹出表单的按钮,在这里我可以添加新作者(

add_book.htmljs代码打开弹出窗口创建新作者

<script type="text/javascript">
$(function () {
$("#create-author").modalForm({
formURL: "{%  url 'author_add' %}"
});
})
</script>
<button id="create-author" class="btn btn-primary" type="button" name="button">
<span class="fa fa-plus"/>
</button>

在这个页面上,我试图粘贴你的JS代码

<script type="text/javascript">
// assume the add author button has an id of add_author_button
$('#create-author').click(function(event){
event.preventDefault();
// assume the text field has an id of author_name
author_name= $('#author_name').val();
create_post(event, author_name);
}
) //<-------- this closing bracket was missing?
function create_post(event, author_name) {
$.ajax({
url: "{%  url '.' %}", // the endpoint I'll precise that in comment
type: "POST", // http method
data: {
author_name: author_name,
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
},
// handle a successful response - data will be a json object returned from your view method
success: function (data) {
if (data.error === null) {
// assume your author multiple choice select has an id of author_sel
// this will append the new author name to the list and will also
// set the value for this author to be the newly created id so you can
// perform other functions on the author like update and/or delete
$('#author_id').append($('<option/>', {
value: data.author_id,
text: data.author_name,
}));
} else {
// display the error on the page
// and/or write it to the console log
console.log(data.error);
}
},
// handle a non-successful http response
error: function (xhr, errmsg, err) {
// display the error on the page
// and/or write it to the console log
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
</script>

缺少一个右括号,所以我添加了JS脚本。我在端点上遇到了问题,当我通过基于类的视图SaveAuthor(view((new_author_add按url名称(时,我得到消息:作者表单无效,但当我使用author_add_view时(author_add按url名(未定义

问题是,当您使用AJAX提交新作者时,作者不会被添加到当前HTML页面中的作者多选字段中。刷新页面将检索新值,但这也会执行整个发布/刷新循环。由于您使用AJAX提交文章,您可以通过JsonResponse返回新作者的id和名称,并使用jQuery将其添加到作者的多选字段中。

views.py

from MyApp.forms import AuthorForm
from MyApp.models import Author
from django.shortcuts import render
from django.views import View
from django.http.response import JsonResponse
class SaveAuthor(View):
template_name = "author/author.html"
def get(self, request):
author_form = AuthorForm()
return render(request,
self.template_name,
{"form": author_form,
"authors":Author.objects.all()})
def post(self, request):
#assume authorForm has author_name defined
author_form = AuthorForm(data=request.POST)
if author_form.is_valid():
author = Author() #here is class name or form name? 
author.name = author_form.cleaned_data['name']
author.save()
return JsonResponse({'author_id':  author.id,
'author_name': author.name})
# error response or whatever you want to return
return JsonResponse({'error':  'author form is not valid'})Your AJAX 

author.html

<!DOCTYPE html>
{% load static %}
<script src="{% static "jquery-3.4.1.min.js" %}"></script>
{% block content %}
<h4>
My author
</h4>
<select id="author_sel" name="author_sel" size="5" class="selectbox">
{% for author in authors %}
<option value="{{author.id}}">{{author.name|capfirst}}</option>
{% endfor %}
</select>
<form id="author-form">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<input type="button" name="button" class="submit_button" id="add_author_button" value="Save">
</form>
<br>
{% endblock %}
<script type="text/javascript">
// assume the add author button has an id of add_author_button
$('#add_author_button').click(function(event){
event.preventDefault();
// assume the text field has an id of author_name
author_name= $('#id_name').val();
create_post(event, author_name);
}) //<-------- this closing bracket was missing?
function create_post(event, author_name) {
$.ajax({
url: ".", // the endpoint I'll precise that in comment
type: "POST", // http method
data: {
name: author_name,
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
},
// handle a successful response - data will be a json object returned from your view method
success: function (data) {
if (data.error === undefined) {
// assume your author multiple choice select has an id of author_sel
// this will append the new author name to the list and will also
// set the value for this author to be the newly created id so you can
// perform other functions on the author like update and/or delete
$('#author_sel').append($('<option/>', {
value: data.author_id,
text: data.author_name,
}));
} else {
// display the error on the page
// and/or write it to the console log
console.log(data.error);
}
},
// handle a non-successful http response
error: function (xhr, errmsg, err) {
// display the error on the page
// and/or write it to the console log
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
</script>

urls.py

from django.urls import path
from . import views
app_name = 'myapp'
urlpatterns = [
# add an author
path('add/', views.SaveAuthor.as_view(), name='author_add'),
]

forms.py

from django import forms
from MyApp.models import Author
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name', ]
widgets = {
'name': forms.TextInput(),
}

型号.py

from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField(max_length=100)

这是一个完整的工作示例。

最新更新