2011-10-07 5 views
5

문서 개체 및 레이블 개체 집합이 있고이 두 개체를 연결해야합니다. 전형적인 다 - 대 - 다 관계입니다. 그러나 더 라벨이되고 있지, 내가 문서를 업로드 할 때모델을 저장할 때 다 - 대 - 다 관계가 언제 그리고 어떻게 생성됩니까?

class DocumentForm(ModelForm): 
    class Meta: 
     model = Document 
     fields = ["title","labels"] 

def upload_document(request): 
    if request.method == 'POST': 
     form = DocumentForm(request.POST, request.FILES) 
     if form.is_valid(): 
      new_document = form.save() 
      return HttpResponseRedirect("/thanks/") 

    else: 
     form = DocumentForm() 

    return render_to_response('upload_page.html', {'form':form}, context_instance=RequestContext(request)) 

,이 데이터베이스에 추가됩니다 :

Models.py :

class Document(models.Model): 
    title = models.CharField(max_length=50, unique=True) 
    title_slug = models.SlugField(max_length=50, unique=True, editable=False) 
    labels = models.ManyToManyField('Label') 

    def save(self, *args, **kwargs): 
     self.title_slug = slugify(self.title) 
     super(Document, self).save(*args, **kwargs) 

class Label(models.Model): 
    name = models.CharField(max_length=40, unique=True) 
    slug = models.SlugField(max_length=40, unique=True, editable=False) 

    def save(self, *args, **kwargs): 
     self.slug = slugify(self.name) 
     super(Document, self).save(*args, **kwargs) 

Views.py 나는 다음과 같은 코드가 있습니다 생성되거나 문서와 연관됩니다. 이 작업을 수행하려면 문서의 save() 함수에 명시 적으로 추가해야합니까? 또는 Views.py 파일의 어딘가에 있습니까? 그것은, 새로운 라벨

  • 잡아 모두 현재가 document_ID를 작성하지 않는 경우에 추가되고있는 레이블이 이미
  • 를 존재하는지

    • 확인 : 나는 뭔가를 갈 것이라고 상상한다 새/기존 label_id
    • 는 내가하는 내장 될 것으로 꽤 표준 기능입니다 내가 그 느낌 (자동 대다 관계에 대해 생성)을 document_labels 테이블

    에 레코드 추가 장고에있는 일대 다 관계,하지만 지금까지 나를 위해 일하는 것 같지 않습니다. 나는 바퀴를 여기에서 재발 명시키는 것을 피하려고 노력하고있다. 다소 django에 새로운.

    미리 감사드립니다.

  • +0

    ? 다른 방법으로'문서'를 추가 하시겠습니까? 무슨 save() 메서드에 대해 이야기하고 있습니까? 'Document','Label' 또는 폼에있는 것? 객체를 저장하는 샘플보기/양식/기타 코드를 제공하십시오. – andreaspelme

    +0

    나는 그것이 정말로 들어가야하는 방법을 잘 모르겠다. 그러므로 내 질문 =] 문서는 모두 사이트의 Form을 통해 추가되고있다. 내가 views.py에서 해당 코드를 포함하도록 질문을 업데이 트했습니다 –

    답변

    4

    django가 그 시점에서 정의되지 않은 Document 객체의 ID가 필요한 "intermediatary join table"을 만들기 때문에 다른 사람이 말한 것처럼 원 샷 Document 객체와 ManyToMany 필드에 저장할 수 없습니다. 그것이 작동하지 않는 경우 the doc

    에 설명 된대로 ModelForm의 save_m2m 기능이 있습니다

    가, 그이, 양식 자체에 의해 호출하도록되어, 어쩌면 트릭은보기에 save_m2m를 호출하는 것입니다 이 같은 기능 :

    def upload_document(request): 
        if request.method == 'POST': 
         form = DocumentForm(request.POST, request.FILES) 
         if form.is_valid(): 
          new_document = form.save() 
          form.save_m2m() 
          return HttpResponseRedirect("/thanks/") 
    
        else: 
         form = DocumentForm() 
    
        return render_to_response('upload_page.html', {'form':form}, context_instance=RequestContext(request)) 
    

    는 희망이 도움이, 스테판

    +0

    아, 문제를 발견했습니다. 예제에서 코드를 단순화하기 위해 new_document = form.save (commit = False)라는 줄을 꺼냈다. 나는 데이터베이스에 저장하기 전에 문서 객체에 대해 더 많은 작업을하고 있기 때문에 commit = False를 사용해야했지만 m2m 저장에 영향을 미치지는 않을 것이라고 생각했습니다. https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#the-save-method에 대한 귀하의 링크는 내가 필요로했던 바로 그 덕분입니다! –

    2

    Django Admin 응용 프로그램이 이런 상황에서 어떻게 작동하는지 언급하는 것이 좋습니다. 일반적으로이 작업은 2 단계 작업입니다. 먼저 여러 개의 레이블을 만든 다음 문서를 만들고 다중 선택 목록에서 원하는 레이블을 선택한 다음 저장합니다. Django는 목록에서 선택된 레이블을 문서와 레이블 사이의 다 대다 테이블을 통해 자동으로 연관시킵니다.

    한 번에이 모든 작업을 수행하려는 경우 inline formsets을 사용할 가능성이 있습니다. 관리 응용 프로그램은 이들을 주로 외래 키 (예 : 설문 및 질문) 용으로 사용하지만 제한된 정도로 다 대다 관계에서도 사용할 수 있습니다.

    경고 : 인라인 서식 설정은 까다로울 수 있습니다. 작업을 두 개의 개별보기로 나눌 수 있다면 훨씬 쉬울 것입니다. 레이블 생성을위한 하나의보기와 문서 작성을위한보기를 작성하기 만하면 문서와 연결할 레이블을 자동으로 선택합니다.

    0

    링크 된 객체는 save()에서 자동으로 생성되지 않습니다. 레이블에 대해 다른 양식을 만들어 명시 적으로 저장해야합니다.

    +0

    나는 다른 * 양식 * 레이블을 만들어야 만 ?? 이는 "문서"양식에서 "레이블"필드를 제거한 다음 동시에 저장하는 것입니까? –

    +0

    예, "Label"필드를 "Document"폼에서 제거하고, 새로운 "Label"폼을 생성 한 다음 저장합니다. –

    2

    문서 모델의 레이블은 M2M 필드이므로 렌더링 된 양식 (시스템에서 사용 가능한 모든 레이블 표시)에서 다중 선택을 렌더링하게됩니다.

    내가 모델에서 라벨의 모델을 업데이트

    def upload_document(request): 
        if request.method == 'POST': 
         form = DocumentForm(request.POST, request.FILES) 
         if form.is_valid(): 
          labels = request.POST.getlist('labels') 
          new_document = form.save() 
          for label_id in labels: # we're only going to add currently defined labels 
           label = Label.objects.get(id=int(label_id)) 
           new_document.labels.add(label) 
          new_document.save() 
          return HttpResponseRedirect("/thanks/") 
        else: 
         form = DocumentForm() 
    
        return render_to_response('doc_form.html', {'form':form}, context_instance=RequestContext(request)) 
    

    views.py
    에, 만약 당신이 원하는 가정.평,

    class Label(models.Model): 
        name = models.CharField(max_length=40, unique=True) 
        slug = models.SlugField(max_length=40, unique=True, editable=False) 
    
        def save(self, *args, **kwargs): 
         self.slug = slugify(self.name) 
         super(Label, self).save(*args, **kwargs) 
    
        def __unicode__(self): 
         return self.name 
    

    당신이 사용자는 즉석에서 레이블을 만들 필요 생각한다면, 당신은 입력 필드와 같은 뭔가 다른, 귀하의 형태로 레이블 필드를 오버라이드 (override) 할 필요가있다. 쉼표로 구분 레이블을 입력하는 사용자를 지시하는 경우 예를 들어, 당신은

    for label in labels: # labels entered by user 
        try: 
         lbl = Label.objects.get(name='label') 
        except Label.DoesNotExist: 
         lbl = None 
    
        if not lbl: 
         lbl = Label() 
         lbl.name = label 
         lbl.save() 
    
        newDoc.labels.add(lbl) 
    
    newDoc.save() 
    

    희망이 당신의 문제를 해결, 같은 업데이트 views.py이 있거나 당신이에서 작업 뭔가를 줄 것이다.

    관련 문제