问题描述
我有以下模型:
由对象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) :
pre>
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()
解决方案为您的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()
...
- 初始化您的modelForms在视图中给他们一个前缀
commit = False
,以便您可以从上一个保存操作保存生成的对象
- 使用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()
...
- when initializing your modelForms in the view give them a prefix
commit = False
so that you can save the resulting object from the previous save operation- 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视图中创建多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!