2012-02-05 3 views
1

다른 모델과 많은 관계가있는 모델이 있습니다. 그들은 둘 다 그들과 관련된 형태를 가지고 있으며, 후자는 formset을 가지고 있습니다.manytomanyfield with modelformset

class Foo(models.Model): 
    name = models.CharField(max_length=20) 
    bars = models.ManyToManyField("Bar",blank=True,null=True) 

class Bar(models.Model): 
    name = models.CharField(max_length=20) 

class FooForm(ModelForm): 
    class Meta: 
    model = Foo 

class BarForm(ModelForm): 
    class Meta: 
    model = Bar 

BarFormSet = modelformset_factory(Bar,form=BarForm,extra=2) 

내보기/템플릿에서는 표준 ManyToManyField 위젯이 formset으로 대체되었습니다. 따라서, 나는 그 formset에 지정된 Bar의 인스턴스를 Foo의 ManyToManyField와 수동으로 연관시켜야한다. 나는 푸의 깨끗한 방법으로이 일을하고있다 :

def clean(self,*arg,**kwargs): 
    cleaned_data = self.cleaned_data 
    # barSubFormInstance is the BarSubForm that is displayed in my view 
    if barFormSetInstance.is_valid(): 
    barInstances = barFormSetInstance.save() 
    cleaned_data["bars"] = barInstances 
    return cleaned_data 

거의 작품. 문제는 Foo.bars를 formset 내의 변경된 양식 집합으로 설정한다는 것입니다. 따라서 하나의 바를 내 foo에 추가 한 다음 양식을 다시로드하고 두 번째 막대를 추가하면 foo는 두 번째 막대 만 갖게됩니다. 장고 문서에 따르면

:

저장() 메소드는 데이터베이스에 저장되어있는 인스턴스를 반환합니다. 주어진 인스턴스의 데이터가 바운드 데이터에서 변경되지 않은 경우 인스턴스는 데이터베이스에 저장되지 않고 반환 값에 포함되지 않습니다 ...

그래서 내 코드가 실패. 나는 그걸 어떻게해야할지 모르겠다. 새로 수정 된 양식을 추가하지만 기존 양식은 삭제하지 않는 cleaned_data [ "bars"]로 전달할 수있는 항목은 무엇입니까?

많은 도움에 감사드립니다.

+0

** 15 분 후에 ... ** [ "바"] 작업 할 _seems_ cleaned_data이 할당 하지만 종류의 해키 느낌 : '[form.instance 양식 barFromSetInstance에서 양식을합니다. cleaned_data]' – trubliphone

답변

0

위의 코멘트에 오류가있었습니다. 그리고 내가 배제 한 다른 세부 사항들.

적절한 코드는 다음과 같습니다

def clean(self,*arg,**kwargs): 
    cleaned_data = self.cleaned_data 
    # barFormSetInstance is the BarFormSet that is displayed in my view 
    # it's already been validated by the time this function is called 
    barInstances = [form.save() for form in barFormSetInstance if form.cleaned_data] 
    cleaned_data["bars"] = barInstances 
    return cleaned_data 

나는 또한 "빈"와 "널 (null)"는 ManyToManyField true로 모두 설정되었는지 확인했다. (나는 왜 그 필드의 is_valid() 메소드를 오버라이드하지 않고 그냥 True를 리턴해야하는지 확신 할 수 없다.).

관련 문제