将AJAX与ModelMultipleChoiceField和自定义表单相结合

时间:2014-07-18 23:11:48

标签: ajax django forms model

我已经敲了一会儿,找不到同样的问题。

我会查看我的代码

型号

class RestauranteMenu(models.Model):

   restaurante  = models.ForeignKey(RestauranteUser)
   name         = models.CharField(max_length=60, blank=False)

class OpeningHours(models.Model):

   ...
   restaurante  = models.ForeignKey(RestauranteUser)
   menu         = models.ForeignKey(RestauranteMenu, blank=True, null=True)
   ...

表格

class MenuForm(ModelForm):
'''
    View = menus(request)
    Template = pages/menus.html
'''

horario = ModelMultipleChoiceField(queryset=OpeningHours.objects.all())

def save(self, restaurante, horario, commit=True):
    #Linking relationship Restaurant x RestaurantMenu
    menu = super(MenuForm, self).save(commit=False)
    menu.restaurante = restaurante
    if commit:
        menu.save()

    #Linking relationship RestaurantMenu x OpeningHours
    horario = OpeningHours.objects.filter(id=horario, restaurante = restaurante).first()
    if horario:
        horario.menu = menu
        horario.save()

    return menu


class Meta:
    model = RestauranteMenu
    exclude = ['restaurante']

查看

def menus(request):
#verify if its an update.
instance = request.POST.get('instance')
if instance not in [None, '']:
    menu = RestauranteMenu.objects.get(id=instance)
    form = MenuForm(request.POST or None, instance=menu, initial={'horario': OpeningHours.objects.filter(restaurante=request.user).values_list('id', flat=True)})
else:
    form = MenuForm(request.POST or None, initial={'horario': OpeningHours.objects.filter(restaurante=request.user).values_list('id', flat=True)})
if request.POST:
    if form.is_valid():
        try:
            #When saving, we pass a restaurant reference and OpeningHours reference.
            form.save(request.user, form.data.get('horario'))

JS

$(document).on("click", "#sendmenuform", function() {
var horariosId = [];

$('#horario :selected').each(function(i, selected) {
    horariosId.push($(selected).val());
});

$.ajax({
    type: "POST",
    url: "../menus/",
    data: {
        name     : $('[name="name"]').val(),
        horario  : horariosId,
        instance : $('#sendmenuform').attr("data-id"),
        csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
    },
    success : function(data) {
         .... process response...

    }
});

问题是什么

根据我的模型,我希望菜单与OpeningHours有一个ManyToOne关系,这意味着一个菜单可以在不同的OpeningHours。

当我提交表单(通过AJAX)时,我无法填写该字段' horario'在表格内。在实例化表单时,我会使用将由该餐厅过滤的查询集填充该字段。

在html上,我有一个选择倍数,因此餐厅可以将一个菜单链接到几个不同的OpeningHours对象。

我不知道我应该如何处理AJAX请求发送给视图的信息,特别是这个ModelMultipleChoiceField。我是否需要覆盖任何表单方法?

1 个答案:

答案 0 :(得分:0)

ModelMultipleChoiceField需要模型对象而不是任意字符串。因此,使用values_list查询集只会让您陷入困境。您的表单不会验证。

对于您的用例,请使用ChoiceFields。您可以通过覆盖__init__方法用字符串填充它们。例如,在您的Forms.py

horario = ChoiceField(
    choices[],)
def __init__(self, *args, **kwargs):
    super(MenuForm, self).__init__(*args, **kwargs)
    self.fields['horario'].choices = [(x.id, x.modelfieldtodisplay) for x in OpeningHours.objects.all()]

如果要在发布表单或加载表单时执行此操作,请在由事件的侦听器触发的视图内执行此操作。您必须编写Javascript来处理类似于this tutorial的问题,但这会要求您使用我不建议您使用的ModelChoiceField,因为当您尝试动态填充多个字段并提交时,它无法正常工作表单,验证它并对数据运行一些操作。

相反,我恳请您看一下Dajax and Dajaxice,这需要花费5分钟来设置和处理表单,而AJAX可以毫不费力地使您的工作变得更加简单。我强调的是,使用ModelChoiceField为您使用大小写无效。我学到了很难的方法。