在django视图中创建多个对象

在django视图中创建多个对象

本文介绍了在ajax文章中,在django视图中创建多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型:
由对象A包含的对象B包含的对象C



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



当通过一个帖子动作提交时, d喜欢创建我的对象树。
我的目标是在验证此模板时创建一个对象树。



目前它的工作原理,但我猜我的解决方案真的很脏:




  • 根据我的表单中有多少元素,使用js / jquery创建列表

  • 使用$传递这些列表。作为数据参数发布

  • 使用请求中的列表,在视图中的django数据模型中创建对象



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




  • 使用多个帖子通过不同的视图创建对象,B和C)? (但同步问题..)

  • 使用json直接在js / jquery端表示对象?

  • 另一个解决方案?



许多感谢 - 为了清楚起见,



编辑:



$ b我的数据模型不同(以前简化过)
所以:
会话是以前的对象A
运动是对象B
重复是对象C
- 为此,我希望这将足够清楚(我将在最后的帖子中更正)



在这里有一些进展,你的帮助家伙:)我已经玩了一些Form和FormSet。显然,它的强大:)



所以现在我有以下的观点:

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

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

如果request.method =='POST':
reuseFormSet = RepetitionFormSet(request.POST)

用户= 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()

如果repeatFormSet.is_valid():
for RepeatForm在repetFormSet.cleaned_data中:
if(,repeatForm.is_valid()):
weight = repetitio nForm.data ['weight']
count = repeatedForm.data ['count']
返回HttpResponse(ok)
else:
repeatedFormSet = RepetitionFormSet()

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

模板侧就像:

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

(更多的代码用于模板添加动态表单实例,因为这个聪明的帖子描述它
,我不会在这里解释)



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



$ p $

如果我正在尝试

  repeatedItem.isValid()

RepetitionForm对象没有属性isValid p>

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



我很卡住:p



我的模型

  class User(models.Model) :
name = models.CharField(max_length = 100)
mail = models.CharField(max_length = 100)
dateCreated = model s.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。模型):
运动= models.ForeignKey(运动)
count = models.IntegerField()
weight = models.IntegerField()
pre>

解决方案

为您的A模型制作模型表单。

  class FormA(forms.ModelForm):
注册表单
class Meta:
model = ObjectA

在您的视图中:

 
#使用Modelformset_factory并排除FK字段
FormBSet = modelformset_factory(ObjectB,exclude =(' objecta',))
FormCSet = modelformset_factory(ObjectC,exclude =('objectb',))

如果request.method ==POST:
forma = FormA request.POST,prefix =forma)
formbset = FormBSet(request.POST,prefix =formbset)
formcset = FormCSet(request.POST,prefix =formcset)
如果forma.is_valid()和formbset.is_valid()和formcset.is_valid():
#save a
a = forma.save()

#将a保存到b $ formbset中的form

b = formb.save(commit = F al $)
b.objecta = a
b.save()

#将b转换为c
for formc中的formc
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 / formets /#formsets)来管理B和C的n *个实例



编辑



使用django.forms.models中的 import modelformset_factory NOT formset_factory,另请注意排除参数。



请参阅:


I have the following model :Objects C, contained by objects B, contained by object A

I a have a dynamic form in a template, and using jQuery functions, I can add dynamically several fields to this form, each group of fields representing Objects (B or C)

When submitted by a post action, I'd like to create my object tree.My objective is to create an object tree when validating this template.

Currently it works, but I guess my solution is really dirty:

  • Creating lists using js/jquery, according how many elements I have in my form
  • Passing theses lists using $.post as data arguments
  • Using the lists in request, creating objects in django data model in a view

I'm quite sure there's a really better solution :p

  • Use multiple post to create Objects through different views (distinct for A, B and C) ? (But sync problems..)
  • Use json to represent objects directly on js/jquery side ?
  • Another solution ?

Many Thanks - edited for clarity

EDIT:

Note :My data model here is different (I'd simplified before)So :Session is former "object A"Exercise is "object B"Repetition is "object C"-Sorry for that, I hope It'll be clear enough (I'll correct in final post)

Some progress here, with your help guys :) I've played a little bit with Form and FormSet. Obviously, its powerfull :)

So now I have the following view:

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

Template side is like :

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

(More code is used in template to add dynamically form instances, as this clever post describes itDjango - Javascript dynamic inline FormSet with autocomplete, i wont explain it here)

Currently, when submitting form, I received this error from view :

"Key 'weight' not found in

If I'm trying a

repetitionItem.isValid()

"RepetitionForm' object has no attribute 'isValid"

The same problem appears if I'm using forms.ModelForm instead of forms.Form

I'm quite stuck :p

My Models

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()
解决方案

Make a Model Form for your "A" model like so.

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

in your view:

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. when initializing your modelForms in the view give them a prefix
  2. commit = False so that you can save the resulting object from the previous save operation
  3. Use Formsets (https://docs.djangoproject.com/en/dev/topics/forms/formsets/#formsets) to manage n* instances of B's and C's

EDIT

use from django.forms.models import modelformset_factory NOT formset_factory, also, note the exclude paramater.

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

这篇关于在ajax文章中,在django视图中创建多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 11:05