2016-08-09 51 views
0

我有兩個從單個視圖提交的模型表單。一個模型是另一個的ForeignKey。此時,表單將添加到數據庫,但並不如預期。我沒有添加課程和部分(課程字段填充了新創建的課程),而是獲取了已鏈接的課程和部分,但使用作爲課程名稱和部分名稱輸入的部分名稱。多個表單提交單個視圖 - Django

models.py

class Course(models.Model): 
    Name = models.CharField(max_length=30,unique=True) 
    Active = models.BooleanField(default=True) 

    def __unicode__(self): 
     return u'%s' % (self.Name) 

class Section(models.Model): 
    Name = models.CharField(max_length=30,default='.',unique=True) 
    course = models.ForeignKey(Course, on_delete=models.CASCADE) 
    assessments = models.ManyToManyField(Assessment) 

    def __unicode__(self): 
     return u'%s/%s' % (self.Name, self.course) 

forms.py

class CourseAddForm(forms.ModelForm): 
    class Meta: 
     model = Course 
     fields = ['Name', 'Active'] 
class SectionAddForm(forms.ModelForm): 
    class Meta: 
     model = Section 
     fields = ['Name'] 

模板/ index.html中

<!-- COURSE ADD MODAL --> 
<div class="modal fade" id="CourseAddModal" role="dialog"> 
<div class="modal-dialog"> 

    <!-- Modal content--> 
    <div class="modal-content"> 
    <div class="modal-header" style="padding:5px 10px;"> 
     <button type="button" class="close" data-dismiss="modal">&times;</button> 
     <h4>Add Course</h4> 
    </div> 
    <div class="modal-body" style="padding:10px 10px;"> 
     <form data-parsley-validate method="post" id="coursesecaddform" action="" enctype="multipart/form-data" 
       data-parsley-trigger="focusout"> 

     {% csrf_token %} 
     Add course 
     {{ courseaddform.as_p }} 
     Add section 
     {{ sectionaddform.as_p }} 

     <p id="login-error"></p> 

     <input type="submit" class="btn btn-info submit" name="AddCourse" value="Add Course" /> 
     </form> 
    </div> 
    <div class="modal-footer"> 
    </div> 
    </div> 

</div> 
</div> 

views.py

def IndexView(request,Course_id,Section_id): 
    if request.method == "GET": 

     this_course = Course.objects.get(pk=Course_id) 
     active_courses = Course.objects.all().filter(Active=True).exclude(pk=Course_id) 
     section_list = Section.objects.all().filter(course=this_course) 
     if len(section_list) >1: 
      multi_section = True 
     else: 
      multi_section = False 
     active_section = Section.objects.get(pk=Section_id) 
     roster = Student.objects.all().filter(sections__in=[active_section]) 
     announcement_list = Announcement.objects.all().filter(sections__in=[active_section]) 
     courseaddform = CourseAddForm() 
     sectionaddform = SectionAddForm() 

     context = {'active_courses':active_courses, 'this_course': this_course, 
        'active_section':active_section, 'section_list':section_list, 
        'roster':roster, 'multi_section':multi_section, 
        'announcement_list':announcement_list, 'courseaddform':courseaddform, 
        'sectionaddform':sectionaddform} 
     return render(request,'gbook/index.html', context) 
    elif request.method == "POST": 
     this_course = Course.objects.get(pk=Course_id) 
     active_courses = Course.objects.all().filter(Active=True).exclude(pk=Course_id) 
     section_list = Section.objects.all().filter(course=this_course) 
     if len(section_list) >1: 
      multi_section = True 
     else: 
      multi_section = False 
     active_section = Section.objects.get(pk=Section_id) 

     f = CourseAddForm(request.POST, instance=Course()) 
     g = SectionAddForm(request.POST, instance=Section()) 
     if f.is_valid() and g.is_valid(): 
      new_course = f.save() 
      new_section = g.save(commit=False) 
      new_section.course = new_course 
      print new_section.course 
      new_section.save() 

     return redirect("/gbook/"+str(Course_id)+"/"+str(active_section)) 

回答

1

解決方案:

代替使用instance說法,使用prefix

def IndexView(request,Course_id,Section_id): 
    if request.method == "GET": 

     this_course = Course.objects.get(pk=Course_id) 
     active_courses = Course.objects.all().filter(Active=True).exclude(pk=Course_id) 
     section_list = Section.objects.all().filter(course=this_course) 
     if len(section_list) >1: 
      multi_section = True 
     else: 
      multi_section = False 
     active_section = Section.objects.get(pk=Section_id) 
     roster = Student.objects.all().filter(sections__in=[active_section]) 
     announcement_list = Announcement.objects.all().filter(sections__in=[active_section]) 
     courseaddform = CourseAddForm(prefix='crs') 
     sectionaddform = SectionAddForm(prefix='sctn') 

     context = {'active_courses':active_courses, 'this_course': this_course, 
        'active_section':active_section, 'section_list':section_list, 
        'roster':roster, 'multi_section':multi_section, 
        'announcement_list':announcement_list, 'courseaddform':courseaddform, 
        'sectionaddform':sectionaddform} 
     return render(request,'gbook/index.html', context) 
    elif request.method == "POST": 
     this_course = Course.objects.get(pk=Course_id) 
     active_courses = Course.objects.all().filter(Active=True).exclude(pk=Course_id) 
     section_list = Section.objects.all().filter(course=this_course) 
     if len(section_list) >1: 
      multi_section = True 
     else: 
      multi_section = False 
     active_section = Section.objects.get(pk=Section_id) 

     f = CourseAddForm(request.POST, prefix='crs') 
     g = SectionAddForm(request.POST, prefix='sctn') 
     if f.is_valid() and g.is_valid(): 
      new_course = f.save() 
      new_section = g.save(commit=False) 
      new_section.course = new_course 
      print new_section.course 
      new_section.save() 

     return redirect("/gbook/"+str(Course_id)+"/"+str(active_section)) 
+0

爲了清楚起見,'instance'允許你預先填充一個帶有數據的表單和/或編輯一個現有的模型實例。 'prefix'在生成的表單域的名稱和ID屬性上添加一個唯一的前綴,這可能是解決問題的理想方法。這不是真正的「實例」或「前綴」選擇,因爲它們做了不同的事情,甚至可以同時使用。再說一遍,我認爲使用'prefix'在這裏是正確的。 – souldeux

+0

謝謝你的背景!這非常有幫助。 – DeltaG

0

兩種型號具有Name場,所以這兩種形式包含具有相同屬性name的輸入。當Django遇到兩個具有相同名稱的POST參數時,它將通過該名稱將最後一個值綁定到所有字段。長話短說 - 改變模型中的字段名稱,使它們不同。

+0

我找到了一個替代解決方案(請參閱上面的答案),但是如果更改這些字段名稱,則允許我的舊代碼按寫入方式工作? – DeltaG

+0

是的,雖然我認爲我更喜歡你的解決方案,但我可以很容易地想象出一種情況,即改變模型字段名至少是麻煩的。 – rafalmp

0

由於您的CourseSection都有所謂Name的屬性,我打賭你的形式與屬性id = "id_Name"name = "Name"兩個字段。