0

OK - I'm positive that the issue is that I have some fundamental understanding of how forms work in Django, so 30,000 ft conceptual explanations are welcome, in addition to code fixes!

I'm trying to run my site from (mostly) a single view (and single template), with modal popups to view info (working) and to edit or add it (not working). I can see the form, fill it out, and click submit, at which point the modal closes, but no new Courses show up in the admin view.

I'll confine this to a single model - my simplest - for the time being:

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)

views.py

def IndexView(request,Course_id,Section_id):
    template_name = 'gbook/index.html'
    print Course_id,Section_id
    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()

    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}
    return render(request,'gbook/index.html', context)

forms.py

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

templates/index.html

...
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span><span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a data-toggle="modal" data-target="#SectionRosterModal">Roster</a></li>
            <li><a data-toggle="modal" data-target="#AnnouncementModal">Announcements</a></li>
            <li><a data-toggle="modal" data-target="#CourseAddModal">CourseAdd</a></li>

          </ul>
        </li>
...
<!-- 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="courseaddform" action="" enctype="multipart/form-data"
                data-parsley-trigger="focusout">

        {% csrf_token %}

        {{ courseaddform.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>
...

I think that there's supposed to be a POST command in there somewhere, but I really don't have a good handle on the process here. Thanks for the help!

DeltaG
  • 606
  • 2
  • 9
  • 22
  • what is the actual problem here? it is not working when you hit submit? or is it not displaying the form? – nkhumphreys Aug 09 '16 at 15:45
  • The form is displayed. When I click, the modal closes, but nothing happens (no additional Courses in admin view) – DeltaG Aug 09 '16 at 15:47

1 Answers1

0

It looks like you are not doing anything with the form data when you post back, you need to process the form if the request method is a POST

def IndexView(request, ...):
    if request.method == "GET":
        ... do what you are doing now and return
    elif request.method == "POST":
         cf = CourseAddForm(request.POST)
         if cf.is_valid():
             ...do stuff with cf.cleaned_data <---- this is a dict
             return ....

You are doing the same thing for GET and POST requests right now and neither deals with the submitted form

see here for more details

https://docs.djangoproject.com/en/1.10/topics/forms/#the-view

EDIT #1:

The POST should be a standard HTTP POST request back to the same URL. Just set the method tag as you are now and action="." (or a URL lookup in the template).

You need to return a valid HTTPResponse object but the normal case when dealing with a form is to return a HTTPResponseRedirect(...some url...) if the form is valid. In the case of a single page app, if you reload the same page you need to do everything you did in the request.method == "GET" so maybe return a HTTPResponseRedirect back to the same URL. In this case, I would look at the django messages framework and add a message to the context saying the form was submitted successfully and display the message in the reloaded page (you should always check if there is a message to display anyway when using the messages framework so this will not break the case where you are loading the page for the first time)

https://docs.djangoproject.com/en/1.9/ref/contrib/messages/

nkhumphreys
  • 866
  • 7
  • 12
  • :) Thanks for the quick answer. That helps. Could you provide a little more info on how to do the POST and what to return? – DeltaG Aug 09 '16 at 15:56
  • @DeltaG the two links in the original and edit should now give you everything you need to get this working smoothely – nkhumphreys Aug 09 '16 at 16:08
  • It's getting close - thanks for the clarification. I can actually add a field to the DB now! Is there a way to, if I have several of these modals/forms in this view, specify which I'm POSTing? Say that I replicate the same thing, but with StudentAddForm - how can I select that for updating? – DeltaG Aug 09 '16 at 16:15
  • that is a separate question and has been answered here: http://stackoverflow.com/questions/1395807/proper-way-to-handle-multiple-forms-on-one-page-in-django If this fixes your current problem, please mark it as answered – nkhumphreys Aug 09 '16 at 16:17
  • One thing that didn't work: I have to set `action = "" `instead of `action = "."` to get it to post correctly. – DeltaG Aug 09 '16 at 18:41
  • you should actually use the `{% url 'url_name' %}` template tag, this is best practice – nkhumphreys Aug 09 '16 at 20:08