【问题标题】:Combining AJAX with ModelMultipleChoiceField and custom form将 AJAX 与 ModelMultipleChoiceField 和自定义表单相结合
【发布时间】:2014-09-10 04:27:35
【问题描述】:

我一直在摸头,找不到类似的问题。

我会检查我的代码

型号

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...

    }
});

有什么问题

根据我的模型,我希望 Menu 与 OpeningHours 建立多对一关系,这意味着一个 Menu 可以在不同的 OpeningHours。

当我提交表单(通过 AJAX)时,我无法在表单中填充“horario”字段。实例化表单时,我使用将按该餐厅过滤的查询集填充该字段。

在 html 中,我有一个选择多个,以便餐厅能够将一个菜单链接到几个不同的 OpeningHours 对象。

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

【问题讨论】:

    标签: ajax django forms model


    【解决方案1】:

    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 是无效的。我很难学到这一点。

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 2016-05-27
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多