Creating a better user interface

There isn't anything complicated about what we'll do here. It should be very easy for you to follow along, so I'll just give you the code to write and leave the explanation, as we have done all of this many times before in the previous chapters.

Start by creating a templates directory in the project root. Next, add it to the list of DIRS in the TEMPLATES configuration variable in our formmason/settings.py file. The settings.py file already has a TEMPLATES variable configured, so go ahead and replace the DIRS list in this dictionary with the value that you see here:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Next, create a base.html template in the new templates directory that you just created and put this code in there:

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />

    <title>Form Mason</title>
</head>

<body>
    <a href="{% url 'home' %}">Home</a>
    {% block content %}
    {% endblock %}
</body>
</html>

Modify main/templates/custom_form.html to match this:

{% extends "base.html" %}

{% block content %}
    <h1>Custom Form</h1>
    <form action="" method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Submit" />
    </form>
{% endblock %}

Change main/views.py to this:

from django import forms
from django.views.generic import FormView
from django.views.generic import ListView

from main.models import FormSchema


class HomePageView(ListView):
    model = FormSchema
    template_name = "home.html"


class CustomFormView(FormView):
    template_name = "custom_form.html"

    def get_form(self):
        form_structure = FormSchema.objects.get(pk=self.kwargs["form_pk"]).schema

        custom_form = forms.Form(**self.get_form_kwargs())
        for key, value in form_structure.items():
            field_class = self.get_field_class_from_type(value)
            if field_class is not None:
                custom_form.fields[key] = field_class()
            else:
                raise TypeError("Invalid field type {}".format(value))

        return custom_form

    def get_field_class_from_type(self, value_type):
        if value_type == "string":
            return forms.CharField
        elif value_type == "number":
            return forms.IntegerField
        else:
            return None

Create a new home template at main/templates/home.html and give it the following code:

{% extends "base.html" %}

{% block content %}
    <h1>Available Forms</h1>
    {% if object_list %}
    <ul>
        {% for form in object_list %}
        <li><a href="{% url 'custom-form' form_pk=form.pk %}">{{ form.title }}</a></li>
        {% endfor %}
    </ul>
    {% endif %}
{% endblock %}

Finally, change formmason/urls.py to match this:

from django.conf.urls import url

from main.views import CustomFormView
from main.views import HomePageView

urlpatterns = [
    url(r'^$', HomePageView.as_view(), name='home'),
    url(r'^form/(?P<form_pk>d+)/$', CustomFormView.as_view(), name='custom-form'),
]

Once you have done all this, open up the home page for the application again at http://127.0.0.1:8000, and you should see a page similar to this:

Creating a better user interface

Clicking on the link for the form should take you to the same form page that we had before; the only difference is that now it is served at the URL, http://127.0.0.1:8000/form/1/.

Like I said, all this is pretty basic stuff that we have done repeatedly in the past few chapters. One thing that might be new is our use of self.kwargs['form_pk'] in the CustomFormView.get_form method. Here's the relevant line:

form_structure = FormSchema.objects.get(pk=self.kwargs["form_pk"]).schema

For any generic view that Django provides (except for the base View class), self.kwargs is a dictionary of all named parameters that matched the URL pattern. If you look at our formmason/urls.py file, we defined the URL for our custom form page like this:

url(r'^form/(?P<form_pk>d+)/$', CustomFormView.as_view(), name='custom-form')

In our view, the form_pk parameter defined in the regex pattern for the URL is available in self.kwargs. Likewise, any non-keyword parameters in the URL pattern are available for use in self.args.

Now that we have a useable user interface, we will move on to storing the form responses in our database and giving our customers a page to view these responses.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.19.75