2014-02-14 29 views
2

我认为我需要做的实际上与inlineformset相反。Django以一种形式编辑模型对象和引用对象

说我有:

from django.db import models 
class Type(models.Model): 
    description = models.CharField(max_length=50) 
    status = models.ForeignKey(Status) 
    def __unicode__(self): 
     return self.description 

class ColorType(models.Model): 
    type = models.ForeignKey(Type) 
    color = models.ForeignKey('Color') 
    status = models.ForeignKey(Status) 
    def __unicode__(self): 
     return u'%s %s' % (self.type, self.color) 

class Color(models.Model): 
    description = models.CharField(max_length=50) 
    status = models.ForeignKey(Status) 
    types = models.ManyToManyField(type, through=ColorType) 
    def __unicode__(self): 
     return self.description 

class Chair(models.Model): 
    description = models.CharField(max_length=50) 
    status = models.ForeignKey(Status) 
    colorType = models.ForeignKey(ColorType) 

现在我需要一个表单编辑我在其中输入彩色椅子和separatedly类型(如显示的的ColorType一个modelformset)。如果组合不存在,应用程序必须创建必要的ColorType实例(并为其分配默认状态)并将其分配给椅子。

我觉得整个情况是常见的,应该是我失去了一些东西......

回答

1

我会发布我自己的解决方案。最后,我通过使用InlineFormsets来完成这个技巧。

在forms.py:

class ChairForm(forms.ModelForm): 
    class Meta: 
     model = Chair 
     exclude = ('colorType') 

class ColorTypeForm(forms.ModelForm): 
    class Meta: 
     model = ColorType 
     exclude = ('status') 

在views.py:

def ChairUpdate(request, chair_id): 
    chair = get_object_or_404(Chair, pk=chair_id) 

    form = ChairForm(instance=chair) 
    ColorTypeInlineFormset = inlineformset_factory(ColorType, Chair, formset=ColorTypeForm) 

    if request.method == 'POST': 
     form = ChairForm(request.POST, instance=chair) 
     if form.is_valid(): 
      chair = form.save(commit=False) 
      colorTypeInlineFormset = ColorTypeInlineFormset(request.POST,) 
      # colorTypeInlineFormset.is_valid() 

      color = Color.objects.get(id=request.POST['color']) 
      type = Type.objects.get(id=request.POST['type']) 

      ct,created = ColorType.objects.get_or_create(color=color,type=type,defaults={'status':Status.objects.get(id=1)}) 
      chair.colorType = ct 

      # marcaModeloInlineFormset.save(commit=False) 
      arma.save() 
      return HttpResponseRedirect(reverse('success_page')) 

    colorTypeInlineFormset = ColorTypeInlineFormset(instance=chair.colorType) 


    return render(request, "chair_form.html", { 
     'chair': chair, 
     'form': form, 
     'colorType_formset': colorTypeInlineFormset, 
     'action': "Update" 
    }) 
1

我做搜索和可悲的是,它目前无法让每个使用仅Django的形式不止一种模式。这就是说,你不是唯一一个想这样做的人。

  • 有一个SO回答here它提出了很好的建议。
  • 如果你仍然想要它,你可以使用something like this来滚动你自己,但有点不同,因为这个版本接受一种形式或另一种形式,而不是一次。
  • 如果你不想自己编写代码,django-multiform是一个Django库,它提供了一种通用的方法来做你想做的事。当然,您需要更改save方法来申请您的用例(ColorType组合等)