【问题标题】:Create multiple objects in a django view from an ajax post从 ajax 帖子在 django 视图中创建多个对象
【发布时间】:2012-11-21 00:56:22
【问题描述】:

我有以下型号: 对象 C,包含在对象 B 中,包含在对象 A 中

我在模板中有一个动态表单,使用 jQuery 函数,我可以动态地向这个表单添加几个字段,每组字段代表对象(B 或 C)

当通过发布操作提交时,我想创建我的对象树。 我的目标是在验证此模板时创建一个对象树。

目前它有效,但我想我的解决方案真的很脏:

  • 根据表单中有多少元素,使用 js/jquery 创建列表
  • 使用 $.post 作为数据参数传递这些列表
  • 使用请求中的列表,在视图中的 django 数据模型中创建对象

我很确定有一个更好的解决方案:p

  • 使用多个帖子通过不同的视图创建对象(A、B 和 C 不同)? (但同步问题..)
  • 在js/jquery端直接使用json表示对象?
  • 另一种解决方案?

非常感谢 - 为清楚起见进行了编辑

编辑:

注意: 我这里的数据模型不同(我之前简化过) 所以 : 会话是以前的“对象 A” 练习是“对象B” 重复是“对象C” -对不起,我希望它足够清楚(我会在最后的帖子中更正)

在你们的帮助下,这里取得了一些进展 :) 我玩了一点 Form 和 FormSet。显然,它的强大:)

所以现在我有以下观点:

class RepetitionForm(forms.Form):
    weight = forms.CharField()
    count = forms.CharField()

def workoutForm(request):
    RepetitionFormSet = formset_factory(RepetitionForm, extra=1)

    if request.method == 'POST':
        repetitionFormSet = RepetitionFormSet(request.POST)

        user = get_object_or_404(User, pk=1)
        session = Session(date=datetime.date.today(), user=user)
        session.save()

        exerciseTypeRef = get_object_or_404(ExerciseTypeRef, pk=1)  
        exercise = Exercise(session = session, exerciseTypeRef = exerciseTypeRef)
        exercise.save()

        if repetitionFormSet.is_valid():
            for repetitionForm in repetitionFormSet.cleaned_data:
                if(repetitionForm.is_valid()):
                    weight = repetitionForm.data['weight']
                    count = repetitionForm.data['count']
        return HttpResponse("ok")
    else:
        repetitionFormSet = RepetitionFormSet()

    return render_to_response('workoutForm.html', {'formSet': repetitionFormSet}, context_instance=RequestContext(request))

模板方面是这样的:

{% csrf_token %}
{{ formSet.management_form }}
<ul id="idUlFormSet">
{% for item in formSet %}
    <li>
    {{ item }}
    </li>
{% endfor %}

(模板中使用了更多代码来动态添加表单实例,正如这篇聪明的帖子所描述的那样 Django - Javascript dynamic inline FormSet with autocomplete,这里就不解释了)

目前,在提交表单时,我从视图中收到此错误:

“未找到键‘权重’

如果我正在尝试

repetitionItem.isValid()

“RepetitionForm”对象没有属性“isValid”

如果我使用 forms.ModelForm 而不是 forms.Form,也会出现同样的问题

我很困惑:p

我的模特

class User(models.Model):
name = models.CharField(max_length=100)
mail = models.CharField(max_length=100)
dateCreated = models.DateTimeField('User creation date')
def __unicode__(self):
    return self.name


class Session(models.Model):
date = models.DateField('Session Date')
user = models.ForeignKey(User)
def __unicode__(self):
    return self.date.strftime("%Y/%m/%d")


class ExerciseTypeRef(models.Model):
name = models.CharField(max_length=100)
desc = models.CharField(max_length=300)
def __unicode__(self):
    return self.name


class Exercise(models.Model):
session = models.ForeignKey(Session)
exerciseTypeRef = models.ForeignKey(ExerciseTypeRef)
def __unicode__(self):
    return self.exerciseTypeRef.name

class Repetition(models.Model):
exercise = models.ForeignKey(Exercise)
count = models.IntegerField()
weight = models.IntegerField()

【问题讨论】:

  • 当你说对象被另一个对象“包含”时——你的意思是外键正确吗?
  • 是的,对不起,C 有 B fk,B a A fk。我说清楚了吗?
  • 好问题。祝你在 Django 上有一个好的体验。你做了正确的选择:)
  • 你有什么运气吗?
  • 昨晚我在玩表格。我是 dj 的初学者,所以.. 必须练习一下! ;) 因为我需要使用 ajax 从表单本身添加表单部分,所以我需要在模板端完成您的示例。无论如何,非常感谢你回答我,我会在几天内让你更新

标签: jquery ajax django


【解决方案1】:

像这样为您的“A”模型制作模型表格。

class FormA(forms.ModelForm) :
    """Signup Form"""        
    class Meta :
        model = ObjectA

在你看来:

from django.forms.models import modelformset_factory
def form(request) :
    # Use Modelformset_factory and exclude the FK fields
    FormBSet = modelformset_factory(ObjectB, exclude=('objecta',))
    FormCSet = modelformset_factory(ObjectC, exclude=('objectb',))

    if request.method == "POST" :
        forma = FormA(request.POST, prefix="forma")
        formbset = FormBSet(request.POST, prefix="formbset")
        formcset = FormCSet(request.POST, prefix="formcset")
        if forma.is_valid() and formbset.is_valid() and formcset.is_valid() :
            # save a
            a = forma.save()

            # save a into b
            for formb in formbset:
                b = formb.save(commit=False)
                b.objecta = a
                b.save()

            # save b into c
            for formc in formcset:
                c = formc.save(commit=False)
                c.objectb = b
                c.save()

        ...
  1. 在视图中初始化你的modelForms时给它们一个前缀
  2. commit = False 这样您就可以保存上一次保存操作的结果对象
  3. 使用 Formsets (https://docs.djangoproject.com/en/dev/topics/forms/formsets/#formsets) 管理 B 和 C 的 n* 个实例

编辑

使用from django.forms.models import modelformset_factory NOT formset_factory,还要注意排除参数。

见:https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#model-formsets

【讨论】:

  • 我不太清楚。 (当然是因为我不太习惯 modelForms)在您的视图示例中,您会收到每个表单中的一个,代表一个 A、一个 B 和一个 C。我的问题是每个提交都应该创建一个 A、nB 和nC 所以我不确定这是否可以解决
  • 我误解了 n* 的要求。给我一点时间来更新我的答案
  • 好吧,我想我明白你在做什么了。我将测试一些表单/表单集。我很快就会回来 :) (我是 django 的初学者,需要一些时间来试验)非常感谢您的回复
  • 对于前端/jquery 部分,您可能想尝试code.google.com/p/django-dynamic-formset。我从未使用过它,但它可能会让您了解 formset + jquery 如何结合在一起
  • 我刚刚编辑了我的答案,关于 formset 与 modelformset 的原始答案中我犯了一个很大的错误,这可能会让你无法理解。
【解决方案2】:

现在可以使用了!

犯了几个错误:

RepetitionFormSet = formset_factory(RepetitionForm, extra=1)
if request.method == 'POST':
    repetitionFormSet = repetitionFormSet(request.POST)
    #should be
    repetitionFormSet = RepetitionFormSet(request.POST)

is_valid IS CRUCIAL(不是填充对象!),我试图调用

repetitionForm.isValid()

这应该是一个 Java 函数,但不存在于 django 表单对象上! (愚蠢的我)

最后,有时我在没有填写字段的情况下测试了我的代码,引发了 KeyError 异常。我不确定这件事是否正常,我现在必须处理这个问题

非常感谢弗朗西斯!

【讨论】:

    猜你喜欢
    • 2011-05-17
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    相关资源
    最近更新 更多