Stefaan
Stefaan

Reputation: 502

How to initialise data on a non model form?

I have a little question regarding Forms / Views which don't use a Model object. I seem to have it set up almost the way it should, but I can't seem to figure out how to pass data around to initialise the fields in my edit form.

What I have to do is get data from a REST server which was developed using Delphi. So this django thingie won't be using the normal django ORM model thing. Currently I have it working so my app displays a list of departmets which it got using a REST call to the server. Each department has it's ID as a hyperlink.

My next step / thing I would like to do is display a form in which the user can edit some values for the selected department. Logically everything seems to be hooked up together the way it should (as far as I can see). Sadly ... for whatever reason ... I can't seem to pass along information about the clicked ID or even the selected object in my list to the detail view.

Would anyone be able to help me out ? This is what I have so far :

The urls.py :

# DelphiClient/urls.py
from django.conf.urls import patterns
from django.conf.urls import url

from . import views

urlpatterns = patterns("",
    url(
        regex=r"^Departments$",
        view=views.DelphiDepartmentsListView.as_view(),
        name="Departments"
    ),
    url(
        regex=r'^Department/(?P<pk>\d+)/$', 
        view=views.DepartmentFormView.as_view(), 
        name='department_update'
    ),
)

The views.py :

# DelphiClient/views.py

...

from .client import DelphiClient
from .forms  import DepartmentForm

class DelphiDepartmentsListView(TemplateView):
    template_name = 'DelphiDepartmentList.html'

    def get_context_data(self, **kwargs):
        client = DelphiClient()
        departments = client.get_department()

        context = super(DelphiDepartmentsListView, self).get_context_data(**kwargs)
        context['departments'] = departments

        #client.update_department(1, 'Update From Django')
        return context

class DepartmentFormView(FormView):
    template_name = 'DepartmentUpdate.html'
    form_class = DepartmentForm
    success_url = '/DelphiClient/Departments'

    def get_initial(self, **kwargs):
        """
        Returns the initial data to use for forms on this view.
        """
        initial = super(DepartmentFormView, self).get_initial(**kwargs)

        # How can I get the ID passed along from the list view
        # so I can get the correct object from my REST server and
        # pass it along in the Initial ???

        return initial

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        print "form.data {0}".format(form.data)
        client = DelphiClient()
        client.update_department(form.data["flddepartmentId"],form.data["flddepartmenet"])

        return super(DepartmentFormView, self).form_valid(form)    

The forms.py :

# DelphiClient/forms.py

from django import forms
from .client import DelphiClient


class DepartmentForm(forms.Form):
    # How can I fill in the values for these fields using an object passed in
    # thhrough Initial or the context?

    flddepartmentId = forms.IntegerField(label="Department ID") #, value=1)
    flddepartmenet   = forms.CharField(label="New Description", max_length=100)    

    def update_department(self, *args, **kwargs):
        #print "update_department"
        #print self.data        
        #print self.data["flddepartmenet"]
        client = DelphiClient()
        client.update_department(self.data["flddepartmentId"],self.data["flddepartmenet"])

And the template for the form :

<h1>Update Department</h1>
<p>Update Department? {{ department.flddepartmentid }}</p>
<p>Something : {{ something }}</p>

<form action="" method="post">
     {% csrf_token %}
     {{ form.as_p }}

     <p><label for="id_flddepartmentId">Department ID:</label> <input id="id_flddepartmentId" name="flddepartmentId" type="number" value="1"></p>
<p><label for="id_flddepartmenet">New Description:</label> <input id="id_flddepartmenet" maxlength="100" name="flddepartmenet" type="text"></p>

    <input type="submit" value="OK">
</form>        

As you can see ... I'm close ... but no cigar yet :-) Since I'm completely new to Python / Django and have been learning on the go, I have no idea what I'm doing wrong or where I should look.

If anyone would be able to help or point me in the right direction it would be really appreciated.

Upvotes: 1

Views: 199

Answers (1)

Alasdair
Alasdair

Reputation: 309029

The positional and name-based arguments are stored in self.args and self.kwargs respectively (see the docs on name based filtering). Therefore you can access the pk with self.kwargs['pk'].

I'm not sure that you should include flddepartmentId as an editable field in the form. It means that users could go to /Department/1/, but then enter flddepartmentId=2 when they submit the form. It might be better to remove the field from the form, then use the value from the URL when calling update_department.

client.update_department(self.kwargs['pk'],self.data["flddepartmenet"])

If you are sure that you want to include flddepartmentId in your form, then your get_initial method should look as follows: def get_initial(self, **kwargs): """ Returns the initial data to use for forms on this view. """ initial = super(DepartmentFormView, self).get_initial(**kwargs)

    initial['flddepartmentId'] = self.kwargs['pk']

    return initial

Upvotes: 1

Related Questions