Front-end prototype/skeleton in Django

1.5k views Asked by At

Often I create a static html prototype/skeleton for back-end developers I work with. This helps to find mistakes in the UI/IA and costly re-writes before the site is implemented.

I would like to take this a step further and create these prototypes/skeletons in Django. By a prototype/skeleton I mean linked static pages that can be easily hooked up to back-end later.

I would like to get some suggestions/ideas how I should set up my templates/links so they are easy to work with later during the implementation stage.

Short list of requirements that come to my mind:

  1. Organization of templates while the entire project will consist of multiple apps
  2. Clean URL dispatcher and link creation
  3. Ability to display logged-in/ logged-out states
2

There are 2 answers

0
Filip Dupanović On BEST ANSWER

I guess in a more traditional approach, the UI designers and back-end developers work on two ends of the development spectrum and hopefully converge somewhere in the middle in a gracious manner. If you'd be willing to get your hands dirty with writing a few lines of code, you could lay out the whole application architecture for the developers because you have the upper hand—your immediately concerned with the users, the data they consume and the interactions they need to perform. That would take out much of the guesswork for the developers, now with only having to fill in the holes, connect the dots or what have you.

The first thing you should do is get together and set some common grounds. Typically, that includes performing modularization at the very beginning. Take all the major features and break them into several Django apps that are going to wrap template, view and model triads relevant to a certain feature the application provides. The more the better holds true here, so don't worry if you end up with a lot of applications, because you never want to have a single application providing too many features/hosting too many components. Commonly you start with apps such as registration, authentication, profiles (user) and work you way outwards. As an example, you could cram the three into a single application, but you end up with a lot of templates, a lot of views, two or three models perhaps, but the tests are really going to be a real choking point. So, break everything into these app buckets until you feel that every part of the system naturally falls into place on a conceptual level. If your ever find yourself thinking where something should be placed, or your looking at a module that's several pages long and feel tempted to break the module (models.py, views.py, test.py) into a package with many intra-package modules, you should probably refactor the architecture immediately. Always remember that your efforts here are to strike simplicity with your architecture.

Once that's done, you've really done half of the work. Great thing about Django is that you have loose coupling between URLs and views. The views themselves provide the application behavior and streamline the presentation. If you can properly pave out the main URLs and stub out the views to just churn out static templates, you've just done some fine work.

This is how it's accomplished. You can abstract URLs and the views they're mapped to by naming your patterns, such as authentication:login, authentication:logout, registration:register, registration:confirm, registration:activate, etc. This is how you tie your internals to all the behaviors that are provided and these shouldn't be subject to change. You can then always change the URL pattern for authentication:login, change the view that pattern maps to, but your referencing it by an internal name, so you can, say, swap out the views that just churned out static templates with a full blown view without having to do any additional modifications to your code.

So here's how it works in real life:

  1. Brainstorm, decide on the apps and the features they'll provide and review your decisions.
  2. Start of with a core application that's going to host some project specific features, such as base templates and the root / view.
  3. Create a /core/templates/core/base.html that's going to load all the common CSS/JS files that are going to be used site-wide, that'll define the header, contents and footer sections (template blocks) and that's going to use context variables for page metadata, such as title, description, keywords and robots. Your typical "One Template To Rule Them All", the bits that are going to be present in structure/presentation for all of your pages.
  4. Create a simple /core/temaplates/core/welcome.html, that extends the core template and prints "Hello world!" in the content area.
  5. Add the following to /core/urls.py:

    from django.conf.urls.defaults import *
    from django.views.generic import TemplateView  
    
    
    urlpatterns = patterns('',
    
        # Welcome
        url(
            r'^$', TemplateView.as_view(template_name='core/welcome.html'),
            name='welcome'
        ),
    
    )
    
  6. Hook it up in the main /urls.py:

    from django.conf.urls.defaults import *
    from django.contrib import admin
    
    
    admin.autodiscover()
    
    urlpatterns = patterns('',
        url(ur'^', include('core.urls', namespace='core')),
        url(ur'^admin/doc/', include('django.contrib.admindocs.urls')),
        url(ur'^admin/', include(admin.site.urls)),
    )
    
  7. Hit http://localhost:8080/, see the "Hello World!", revel in the warm fuzzy feeling.

  8. Repeat the same for the rest of the apps: create the app, create the patterns, name them, map them to a static template, hook it to a namespace in the main urlconf.

You can push the views even further to production readiness for the developers. It might depend on the devs and their style guidelines, but I like to keep my /urls.py clean of everything else but patterns, names and view mappings. Your /core/urls.py could look like:

from django.conf.urls.defaults import *
from core import views


urlpatterns = patterns('',

    # Welcome
    url(
        r'^$', views.Welcome.as_view(),
        name='welcome'
    ),

)

Edit /core/views.py with the following:

from django.core.views.generic import TemplateView

class WelcomeView(TemplateView):

    template_name='core/welcome.html'

    extra_context={
        'page_title': 'Welcome!',
        'page_keywords': 'relevant,page,keywords',
        'page_description': 'Something equally relevant',
    }

    def get_context_data(self, **kwargs):
        context = super(WelcomeView, self).get_context_data(**kwargs)

        context.update(self.extra_context)
        return context

And that's one sturdy stubbed-out view, packed with page metadata! Definitely the stuff that'll earn you a beer from the devs. Keep on doing this for all of the views to pump out static templates. When someone approaches to finalizing the views, they'd just have to inherit from a different view class, add the missing features, extend the context, modify the template and voila--it's ready for production.

There's not a lot of upfront learning you'd have to do to make this possible, but it really takes out a lot of the guesswork for devs, which are naturally more concerned with building the rest of the application. It's also simple enough to get really good at, I would guess no one would mind letting you do all of this work. As added beef, you'll probably not be kept in the dark as to how the template context gets populated in the views, so even you can start rolling out more complex views, or at least be able to read them.

0
lovefaithswing On

When I start an application, I usually make a prototype version as well in Django. I just use direct_to_template generic views, which can later be replaced with the views that the developers create. Since you have multiple apps, you can store app specific templates in a folder in your templates folder that has the same name as the app.

The end result is that you have all the screens displaying at the right urls and can link between them. All developers need to do is replace each url with the custom view they create. Makes it easy.

You may have to do a bit of code if you want the logged in/out status to display, but it is definitely doable.