0

내 Django 웹 페이지 중 하나에서 특정 모델 (Meeting)의 각 인스턴스에 대한 아이콘 (모델 인스턴스 당 하나의 아이콘)을 표시하고 있습니다.Django 양식 __init__ 메서드가 두 번 호출됩니다.

사용자가 아이콘 중 하나를 클릭하면 양식이 페이지의 다른 위치에 표시되어 사용자가 해당 모델의 특정 인스턴스에 대한 세부 정보를 입력 할 수 있습니다. 폼의 필드 필드에 대한 모든 세부 정보를 입력하면 '업로드'버튼을 눌러 입력 한 정보를 데이터베이스에 업로드하고 정보를 모델의 해당 인스턴스에 저장할 수 있습니다.

양식을 제출하면 페이지가 새로 고쳐지고 특정 모델의 각 인스턴스에 대한 아이콘이 표시됩니다. 사용자가 기존 아이콘을 클릭하고 양식의 입력란을 변경하고 '업로드'를 클릭하면 해당 모델의 새 인스턴스가 수정 된 필드로 채워진 양식으로 만들어집니다.

'업로드'버튼을 클릭 할 때마다 Meeting 모델의 인스턴스를 하나 더 만들어야합니다. 양식의 각 필드는 Meeting 모델 속성 중 하나를 나타냅니다.

Meeting의 인스턴스에 이미지 파일을 첨부하기 위해 두 개의 버튼이 있는데, 그 중 하나는 현재 작동합니다. 이미지를 첨부하여 '업로드'를 클릭하면 페이지가 새로 고침되고 모델의 해당 인스턴스에 대한 양식에 첨부 된 이미지가 표시됩니다.

그러나 다른 버튼을 사용하여 이미지를 첨부 한 후 '업로드'를 클릭하면 페이지가 새로 고쳐지고 Meeting 모델의 몇 가지 추가 인스턴스가 양식의 모든 입력란이 비어있는 상태로 웹 페이지에 표시됩니다. , 이미지 파일이 첨부되지 않았습니다 (입력 된대로 저장된 모든 필드와 이미지 파일이 첨부 된 이미지 파일도 생성됩니다).

이 특정 버튼을 통해 이미지를 업로드 할 때 Meeting 객체의 인스턴스가 두 개 이상 생성되는 이유를 알아 내려고 노력하면서 내 코드에 디버그를 추가했습니다. 특히 내가 업로드하는 데 사용하는 양식에 디버그를 추가했습니다. 이 정보 & 데이터베이스에 이러한 이미지 :

class BudgetPresentationForm(ValidatedForm): 
    """ Provides the form for the formset BudgetPresentationFormset """ 
    presentation_minutes = EasyText(field_class="medium", label='Client presentation notes') 
    presentation_date = MoonDateTimeField(required=False, widget=forms.DateTimeInput(format='%d/%m/%Y %H:%M', attrs=({'class':'datetimepicker presentation_date', 'name':'presentation_date2'}))) 
    presenter1 = forms.CharField() 
    presenter2 = forms.CharField() 
    presenter3 = forms.CharField() 
    presenter4 = forms.CharField() 

    class Meta: 
     model = Budget 
     fields = ('presentation_minutes', 'presenter1', 'presenter2', 'presenter3', 'presenter4', 'presentation_date', 'pdf_package_dep') 

    def __init__(self, *args, **kwargs): 
     self.instance = kwargs.get('instance', {}) 
     budget = self.instance 

     if hasattr(budget, 'id'): 
      self.presenters = budget.presenters.all() 

      if budget.presentation_date: 
       print("Budget meeting: ", budget.meeting) 
       pres_meeting = budget.meeting or Meeting.objects.create(project=budget.project, purpose='7') 
       print("Meeting created in projects/forms.py BudgetPresentationForm (line 1055): ", pres_meeting) 
       self.pres_meeting_id = pres_meeting.id 
       self.pres_meeting_creator = pres_meeting.event_creator or '' 
       if not budget.meeting: 
        budget.meeting = pres_meeting 
        budget.save() 
       if not budget.meeting or not pres_meeting.date: 
        pres_meeting.date = budget.presentation_date 
        pres_meeting.save() 
       print("Meeting object is: ", pres_meeting.id) 
       #print("Process ID: ", os.getpid()) 
     else: self.presenters = [] 

     super(BudgetPresentationForm, self).__init__(*args, **kwargs) 
     # if hasattr(self, 'pres_meeting_id'): self.fields['presentation_date'].widget.attrs['data-meeting-id'] = self.pres_meeting_id 
     self.fields['presentation_date'].widget.attrs.update({'data-meeting-id': getattr(self,'pres_meeting_id', ''), 'data-meeting-creator': getattr(self,'pres_meeting_creator', '')}) 

     initial_presenters = [(e.id, e.full_name) for e in self.presenters]+[None, None, None, None]#[(None, ''), (None, ''), (None, ''), (None, '')] # Always at least four so that first four can populate form fields 
     if initial_presenters[0]: self.fields['presenter1'] = FlexiSelect(initial=[initial_presenters[0]], current_id='', url_code='ee', choices=[], required=False, instant='', class_name="autocomplete", label='Who is presenting') 
     else: self.fields['presenter1'] = FlexiSelect(initial=[(None, '')], current_id='*', url_code='ee', choices=[], required=False, instant=' instant', class_name="autocomplete", label='Who is presenting') 
     if initial_presenters[1]: self.fields['presenter2'] = FlexiSelect(initial=[initial_presenters[1]], current_id='', url_code='ee', choices=[], required=False, instant='', class_name="autocomplete", label='') 
     else: self.fields['presenter2'] = FlexiSelect(initial=[(None, '')], current_id='*', url_code='ee', choices=[], required=False, instant=' instant', class_name="autocomplete", label='') 
     if initial_presenters[2]: self.fields['presenter3'] = FlexiSelect(initial=[initial_presenters[2]], current_id='', url_code='ee', choices=[], required=False, instant='', class_name="autocomplete", label='') 
     else: self.fields['presenter3'] = FlexiSelect(initial=[(None, '')], current_id='*', url_code='ee', choices=[], required=False, instant=' instant', class_name="autocomplete", label='') 
     if initial_presenters[3]: self.fields['presenter4'] = FlexiSelect(initial=[initial_presenters[3]], current_id='', url_code='ee', choices=[], required=False, instant='', class_name="autocomplete", label='') 
     else: self.fields['presenter4'] = FlexiSelect(initial=[(None, '')], current_id='*', url_code='ee', choices=[], required=False, instant=' instant', class_name="autocomplete", label='') 

BudgetPresentationFormset = inlineformset_factory(Project, Budget, form=BudgetPresentationForm, max_num=30, extra=1, can_delete=False) 

하지만이 (가) 모든 필드에 정보를 입력하는 데,이 양식에 대한 '제출'버튼을 클릭하고 폼에 이미지 파일을 첨부, 내 콘솔 그 내부의 코드는 다음과 같습니다 :

if budget.presentation_date: 

두 번 실행됩니다. 즉,이 코드를 한 번만 실행해야하는 콘솔에서 동일한 출력을 복제합니다. 양식 제출 후 웹 페이지를 다시로드 할 때 실행될 때).

콘솔 출력을 보여줍니다

('예산 회의 :')

('프로젝트에서 만든 모임/forms.py BudgetPresentationForm (라인 1055) :')

(회의의 목적은 다음과 같습니다 ', 11012L)

('예산 회의 : ')

(회의 projec에서 만든 ts/forms.평 BudgetPresentationForm (라인 1055) : ')

(회의의 목적은 다음과 같습니다', 11078L)는

이런 일이되는 이유 Google'd 데, 코드가 있음을 수 있습니다 나타납니다 두 개의 개별 스레드에 의해 실행되는 이유는 이것이 두 번 실행되는 이유입니다 ...

이 경우입니까? 그렇다면 왜 그렇게됩니까? 코드가 한 번만 실행되고 데이터베이스에 중복 정보가 저장되지 않도록하려면 어떻게해야합니까?

내가 ....

편집 주석의 요청으로

훨씬 전에 스레드와 함께 일하지, 그래서 이것에 대해 어떤 작업을 수행하는 방법/정말 모르겠습니다했습니다 &는 답변 -

: 나는 formset을 사용하고 장소 (내가 Meeting에 대한 세부 정보를 입력이 발표 &에게 양식을 표시하고있는 페이지 인) concept에 대한 view에 입었네

upload_budget_pdfs(request, project_id):view (이는 양식을 업로드하고 업로드하는 데 사용되는 view입니다. 당신은 항목 집합에 대해 반복하는 형태가

def upload_budget_pdfs(request, project_id): 
    project = Project.objects.get(id=project_id) 
    print("Value of project in 'upload_budget_pdfs()': ", project) 

    if request.method == 'POST': 

    presentations = project.budget_versions.select_related('meeting').prefetch_related('budget_items', 'cci_items', 'presenters').filter(version_number__isnull=False).annotate(vn=F('version_number') * -1).order_by('presentation_date', 'created', '-vn') 
    print("Value of presentations in 'upload_budget_pdfs()': ", presentations) 
    drawing_formset = DrawingUploadFormset(request.POST, request.FILES, prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created')) 

    if drawing_formset: 
     print "Before", [b.id for b in project.budget_versions.all()]   
     try: 
      for drawing_form in drawing_formset: #ERF(24/01/2017 @ 1610) This line is what's causing the MultiValueDictKeyError 
       print 'drawing for loop entered in upload_budget_pdfs() - line 1034 ' 
       if drawing_form.instance.budget: 
        print 'if statement entered - line 1036 ' 
        print 'Instance: ', drawing_form.instance.budget 
        drawing = drawing_form.save(commit=False) 
        drawing.budget = drawing_form.instance.budget 
        drawing.save() 
       print drawing, [b.id for b in project.budget_versions.all()] 
     except Exception as e: 
      print '%s (%s)' % (e.message, type(e)) 
    else: 
     print("Drawing formset not valid. ", drawing_formset.errors) 

    budget_formset = BudgetPresentationFormset(request.POST, request.FILES, instance=project, prefix="presentations") 

    if budget_formset: 
     try: 
      # Add a boolean so that budget is only added to form once 
      budgetSaved = False 
      for budget_form in budget_formset: 

       if budget_form: 
        if budgetSaved == False: 
         print 'if statement entered - line 1081 ' 

         budget = budget_form.save(commit=False) 

         budget.save() 
         budgetSaved = True 

     except Exception as e: 
      print '%s (%s)' % (e.message, type(e)) 
    else: 
     print("Budget formset not valid. ", budget_formset.errors) 

    return HttpResponseRedirect(reverse('projects:concept', args=[project_id])) 
+1

아니요, 요청이 단일 스레드에 의해 처리됩니다. 확실히 이것은 여러 폼을 포함하는 formset을 가지고 있기 때문입니다. –

+0

알겠습니다. 예, 여러 양식을 포함하는 양식 세트가 있습니다. 페이지에 표시된 각 프레젠테이션의 양식 (즉, 각 '회의'개체의 양식)이 있습니다. 양식은 사용자가 주어진 프리젠 테이션에 대해 '편집'버튼을 클릭했을 때만 페이지에 표시됩니다. 그러나 지금은 '회의'객체를 나타내는 두 개의 추가 '프리젠 테이션'이 웹 페이지에 표시됩니다 '업로드'버튼을 클릭하면 '예산'이미지를 '회의'에 업로드 할 수 있습니다. 이유는 무엇입니까? – someone2088

+0

아마도보기를 표시해야합니다. –

답변

0

의 formset으로 의미 : 내가 무엇을) 폼에 PDF를 '연결'을 사용하고 있습니다. 해당 formset을 사용하는 위치/방법 코드를 표시해야합니다. 아마도 그것이 문제의 원점이 어디에 있는지입니다.

Link to Django Formsets

+0

formset은 my OP :'BudgetPresentationFormset = inlineformset_factory (프로젝트, 예산, form = BudgetPresentationForm, max_num = 30, extra = 1, can_delete = False)'에 나와있는 것처럼 form.py의 정의 바로 아래에 정의되어 있습니다. . 나는 폼과 formset을 내 OP에도 사용하고있는'views'를 추가했습니다. – someone2088

관련 문제