Codejoy
Codejoy

Reputation: 3814

How form action works in django when using a class in views.py for form creation

I am building a form in django based on my models. I have this in my views.py:

class GroupCreateView(CreateView):
    model = Group
    form_class = GroupForm
    template_name = 'ipaswdb/group/group_form.html'

the template is looking good with some nice form css and a datepicker and the like. I also created a form so I can add widgets in my forms.py

class GroupForm(forms.ModelForm):
    notes=forms.CharField(widget = forms.Textarea)
    billing_address = forms.ModelChoiceField(queryset=Address.objects.all(), widget=forms.Select(attrs={'tabindex':'5'}))
    start_date = forms.DateField(widget=forms.TextInput(attrs=
                                {
                                    'class':'datepicker',
                                    'tabindex' : '5',
                                    'placeholder' : 'Groups start date'
                                }))

    class Meta:
        model=Group
        exclude = ['created_at', 'updated_at']

All this makes sense to me, I can see how the form is constructed based off my model and gets populated with things say in the ModelChoiceField etc.. I am just not sure how the def some_method in my views.py comes into play. So in my form template for the form action I have this:

<h1> Add a new Group </h1>
    <form action="." method="post">
    {% csrf_token %}
  <div class="col-2">
    {{ form.group_name.errors }}
    <label>
      Group Name:
      <input placeholder="Enter the groups name" id="id_group_name" name="group_name" tabindex="1">
    </label>
  </div>
  <div class="col-2">
        {{ form.group_contact.errors }}

    <label>
      Gorup Contact
      <input placeholder="Enter the groups contact name" id="id_group_contact" name="group_contact" tabindex="2">
    </label>
  </div>

  <div class="col-2">
    {{ form.tin.errors }}
    <label>
      TIN Number
      <input placeholder="Groups TIN#" id="id_tin" name="tin" tabindex="3">
    </label>
  </div>
  <div class="col-2">
    {{ form.npi.errors }}
    <label>
      NPI Number
      <input placeholder="Groups NPI#" id="id_npi" name="npi" tabindex="4">
    </label>
    etc etc etc

Which I think calls some default method in the view? I am just not sure what that method is. This is also for adding a new group, I am guessing I need another view or something to handle the case where they are editing an already existing group? This blog demo I was using did it all in the views.py with a forms.py as well thought here was no class GroupCreateView(CreateView): esque method in the example I was working off of in the views.py, there was this method (Note not my method):

def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,
                            status='published',
                            publish__year=year,
                            publish__month=month,
                            publish__day=day)

    comments = post.comments.filter(active=True)
    #their form stuff
    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.post = post
            new_comment.save()
    else:
            comment_form=CommentForm()

    return render(request,
                    'blog/post/detail.html',
                    {'post': post, 'comments':comments, 'comment_form':comment_form})

My question is (and I cannot remember what example to quote it)but what is the class GroupCreateView(CreateView): really doing and how can I get the form it references/creates to come back to call the right action ultimately letting me validate and save to the database?

Also a second sort of part is, how could I extend this (roughly) to handle the case where it is adding a new group, and also maybe another case where it is editing an existing one? (I ask this second question here because I am sure it relates to the answer from the first).

From my urls.py

    url(r'group/add/$', GroupCreateView.as_view(), name='group-add'), 

Upvotes: 1

Views: 1261

Answers (1)

pleasedontbelong
pleasedontbelong

Reputation: 20102

Dont be afraid to read django's source code :P, the generic class has two methods: "get" and "post" (and "put" too, but it calls "post") you can overwrite any of them if you need to.

class BaseCreateView(ModelFormMixin, ProcessFormView):
    """
    Base view for creating an new object instance.

    Using this base class requires subclassing to provide a response mixin.
    """
    def get(self, request, *args, **kwargs):
        self.object = None
        return super(BaseCreateView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = None
        return super(BaseCreateView, self).post(request, *args, **kwargs)

but it also inherits the methods of it's parents so it could be a little hard to read. I always check the docs for the generic views, it gives you a list of all the methods that you can overwrite on every generic class. Now you can overwrite all the methods you want without repeating code (that's why I <3 CBV)

I think in your case you might want to overwrite the form_valid() method to do something before redirecting to the success page

Hope this helps

Upvotes: 2

Related Questions