Django:如何在ajax中返回模型formset并在模板中使用

我需要在运行时使用ajax动态地将表单添加到我的formset,我指的是使用Ajax动态地将表单添加到Django formset

我在同一页面上有多个不同前缀的formset。

我的模型设计如下:用户可以拥有多部手机。 手机可以有多行(如果需要详细信息) 访问Formsets中的多对多“通过”关系字段

用户添加新手机后,我会使用ajax保存手机。 该观点如下

def addUserPhone(request, customer_id, location_id, user_id, **kwargs): error_msg = u"No POST data sent." context = {} if request.is_ajax(): if request.method == "POST": user = End_User.objects.get(id=user_id) phone_client = PartialPhone_ClientForm(request.POST, prefix='new_client') instance = phone_client.save() #associate user to a phone instance.end_user.add(user) #Creating an empty lineFormset for a phone LineFormSet = modelformset_factory(Line, form=Line_Form, can_delete=True) client_lines = LineFormSet(queryset=Line.objects.none(), prefix='phone_client_'+str(instance.id)) # how to return the two objects instance and client_lines back to the template?? #format = 'json' #mimetype = 'application/javascript' #data = serializers.serialize(format, [instance]) #return HttpResponse(data) #can we return as a context?? this gives me only a string "phoneline_set" in the template context['phone'] = instance context['line_set'] = client_lines return HttpResponse(context) else: error_msg = u"Insufficient POST data (need 'Name ' and 'Telephone Number'!)" else: error_msg = "Non Ajax" return HttpResponseServerError(error_msg) 

什么是现在返回手机实例的最佳方法,并将LineFormSet返回到视图以便在模板中呈现?

如果我只返回一个上下文,我的视图只获得字符串“phoneline_set”。 但我想做点什么

  $.post("addUserPhone/",phoneData,function(data){ $('.scroll').append("

{{ line_set }}

") });

如果我使用Json序列化并传递我如何传递LineFormSet并在模板中使用它? 目前,如果我尝试序列化我的client_lines formset,我得到错误AttributeError:’LineFormFormSet’对象没有属性’_meta’

任何帮助表示赞赏,谢谢!!

您不会将上下文作为Ajax响应发送,而是使用该上下文发送呈现的模板片段。 模板应该只是包含要插入div的表单的HTML。

正如评论中所要求的那样,详细阐述丹尼尔的回答。

Django是一个MVC风格的框架。 模型用于存储和访问数据。 在Django中,控制器被称为视图,它具有从具有特定URL的用户获取请求的工作,获取可能与URL关联的一些数据,然后通过某些tempalte推送该数据,这将使用数据视图给它为了填写模板内的占位符。

这是一个简单的例子,解释了所有方面。 想象一下,有一个网站有一个书籍数据库。 因此,您的模型将存储与每本书相关的信息 – 标题,作者,ISBN号等。

 # models.py class Book(models.Model): title = models.CharField(max_length=64) author = models.CharField(max_length=64) isbn = models.CharField(max_length=64) 

现在,您要添加一个URL example.com/book// ,它将显示有关具有指定ID的图书的所有信息。 要做到这一点,需要做一些事情。 第一个Django控制器必须用这种模式捕获url。 您可以在urls.py文件中指定url模式。

 # urls.py urlpattern('', url(r'^book/(?P\d+)/$', views.book), ) 

由于urls.py指定了url模式和视图之间的映射,这告诉Django每当用户转到具有指定模式的URL时,Django必须将请求提供给将知道该做什么的视book 。 另外Django会将书籍ID传递给视图。

 # views.py def book(request, id): # get the book book = get_object_or_404(Book, pk=id) context = { 'book': book } return render_to_response('book_template.html', context) 

所以在视图内部,给定书的ID,它使用模型从数据库中查找书籍,如果没有找到它,它会向用户返回404错误。 然后它填充一个字典,我称之为context ,其中包含一些将传递给模板的值。 模板的工作是获取此context字典并使用其中的值以填充模板内的一些占位符。

 # book_template.html  ...  

{{ book.title }}

Author: {{ book.author }}

ISBN: {{ book.isbn }}

因此,模板将从视图中获取上下文,然后在上下文中使用book以填充{{ }}中的值。

在您的情况下,您试图将一个上下文返回给用户,这没有多大意义。 您需要做的是创建一个模板,该模板将采用该上下文{ 'phone': instance, 'line_set': client_lines }并根据它,将呈现一些将返回给用户的HTML。 您可以使用AJAX拉取HTML,然后根据需要使用它。

希望这能为您澄清一些概念。

Django文档很好,所以我建议也阅读介绍。 它将解释我在这个答案中使用的所有语法和一些快捷方式( render_to_response等)。