Develop a CRUD Movie app with Django 1.7

Getting stated with Django 1.7 and implementing simple CRUD

1. Create django_movie project

We will create a Django project with Python 3.4.1 and Django 1.7 called django_movie project.

django-admin.py startproject movie_project 

Change the current cusor to project foler django_movie and use django built-in server to run the project

manage.py runserver 127.0.0.1:8000

Browse localhost:8000 you will see the result:

Run the project

Our web app doesn’t have anything to browse until now. We need to add more code for our website.

2. Create MovieLib app and the landing page

Call the below command to create MovieLib app in

manage.py startapp MovieLib

Open settings.pyand add MovieLib to INSTALLED_APPS setting:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'MovieLib',
) 

In the MovieLib/views create the index view method for handle the http://localhost:8000/ request:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello Django!") 

On the above code, we define index method with return an HttpResponse object with content Hello Django!. But it’s not enough, we need to change urls.py inside movie_project directory by adding a new line:

from django.conf.urls import patterns, include, url
from django.contrib import admin

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'movie_project.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'MovieLib.views.index'), #index method inside /MovieLib/views.py will handle the `/` request 

)

Browse http://localhost:8000/ again, and you will see the result:

Result

But, it’s just a page with a text on it. I want to have better content to deliver to users.

3. Create home page using template

I want to store all URLs related to MovieLib app in MovieLib folder, and use view class instead of view method. So I will delete the index method created in section 2 and also delete the below line in movie_project/urls.py:

url(r'^$', 'MovieLib.views.index'), #index method inside /MovieLib/views.py will handle the `/` request 

Then, I will create an IndexView class inside MovieLib/views.py:

from django.views.generic import TemplateView

# Create your views here.
class IndexView(TemplateView):
    template_name = 'index.html'

The IndexView class inherits from TemplateView class, so it will pick the index.html template (defined by the last sentence of the above code listing) to render as a HTML page.

Then create a new urls.py file inside MovieLib folder, the urls.py will contain all URLs for MovieLib app:

from django.conf.urls import patterns, url
from MovieLib import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view()),
)

Until now, we do not have the index.html template. We will create a templates folder inside MovieLib folder. And then create our index.html inside templates folder:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>LANDING PAGE</title>
</head>
<body>
    <h1>LANDING PAGE</h1>
</body>
</html>

And result is:

Landing page

How about a better web template by using BootStrap? Yes, we can, but its require us to have some static file like (CSS, images). I choose the starter template form BootStrap homepage. And now the index.html content is as below:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Movie Library</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

    <!-- Custom styles for this template -->
    <link href="{% static "site.css" %}" rel="stylesheet">

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">MovieLib</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Index</a></li>
        <li><a href="#about">Create</a></li>
      </ul>
    </div><!--/.nav-collapse -->
    </div>
    </div>

    <div class="container">

    <div class="starter-template">
        <h1>Movie Listing</h1>
        <p class="lead">All movies should be listed here!</p>
    </div>

    </div><!-- /.container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>

There are two lines you should focus:

    {% load staticfiles %}
    <link href="{% static "site.css" %}" rel="stylesheet">

The first line is for declare that we will generate some link references to static file. The second line using static directive to generate static link to site.css. Where should we store the site.css file? By default Django looks for static file in static folder inside app folder (\MovieLib), so we need to create a static folder, and add a new site.css file inside it with content:

body {
    padding-top: 50px;
}
.starter-template {
    padding: 40px 15px;
}

Now, browse homepage again:

New home page

4. Creating base template

A template for listing (landing) page is good but not enough, we will create a base template for all page in MovieLib app.

Now we create /MovieLib/templates/base_page.html:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Movie Library - {% block title %}{% endblock %}</title>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">


    <!-- Custom styles for this template -->
    <link href="{% static "site.css" %}" rel="stylesheet">

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">MovieLib</a>
            </div>
            <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Index</a></li>
                <li><a href="#about">Create</a></li>
            </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>

    <div class="container">

        <div class="starter-template">
        {% block content %}{% endblock %}
        </div>

    </div><!-- /.container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>

There’re two lines on the above code listing are for defining two Django blocks:

<title>Movie Library - {% block title %}{% endblock %}</title>
...
{% block content %}{% endblock %}

Now, we will edit the index.html template to inherit form the base_page.html template:

{% extends "base_page.html" %}

{% block title %}Movie listing{% endblock %}

{% block content %}
    <h1>Movie Listing</h1>
    <p>Movie list goes here</p>
{% endblock %}

Now, as you can see, the index.html is smaller and it’s easier to maintain and change app UI template by just editing base_page.html rather than modifying all pages.

5. Create Movie model

Open MovieLib/models.py and add code to define Movie class:

from django.db import models


# Create your models here.
class Movie(models.Model):
    title = models.CharField(max_length=128)
    genre = models.CharField(max_length=128)
    release_date = models.DateField()
    price = models.DecimalField(max_digits=20, decimal_places=0)

I choose to use sqlite as the database to store all movie. You can easily change to MySQL or PostGreSQL if you want to without fear because Django ORM supports for MySQL, PostGreSQL and Sqlite as well.

Open the settings.py and you will see database configuration setting part:

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

The default database provider is Sqlite and the default database name is db.sqlite3. We keep using the default database configuration.

6. Create database

Create database structure is quite easy, if your DB configuration settings is correctly, just call the below command and all tables will be created inside the database:

manage.py syncdb

During executing the command, it asks you to create a super admin account:

syncdb

Actually, at this time, there’s no movie table is created in the database. We need to add some migrations.

In previous versions of Django, we need to have South to apply migration. However, from Django 1.7, it has built-in data migration functions.

Now we ask manage.py to make migration:

manage.py makemigrations

If you want to see the SQL migration query for the first migration, you can call:

manage.py slqmigrate MovieLib 0001

Sql migrate

The table name is not Movie but MovieLib_movie, because Django has put a prefix (app name) before table name.

Then, ask manage.py to execute migration:

manage.py migrate 

First migrate

Until now, there is no records in MovieLib_movie table, but you can add some records by using Django shell

manag.py shell

Add new movie record

You can see how many Move records in database as well:

Movie records

4. Change Index view to show movie listing

First thing first, we have to change the IndexView class inside MovieLib/views.py

from django.views.generic import ListView
from MovieLib.models import Movie

# Create your views here.
class IndexView(ListView):
    template_name = 'index.html'
    model = Movie

The IndexView now inherits ListView class and we set model property to Movie class so we can access to show all movies on index.html template.

Secondly, change the index.html template:

{% extends "base_page.html" %}

{% block title %}Movie Listing{% endblock %}

{% block content %}
<h1>Movie Listing</h1>
<table class="table">
    <tr>
        <th>Title</th>
        <th>Genre</th>
        <th>Price</th>
        <th>Release Date</th>
        <th></th>
    </tr>
    {% for movie in object_list %}
        <tr>
            <td>{{ movie.title }}</td>
            <td>{{ movie.genre }}</td>
            <td>{{ movie.price }}</td>
            <td>{{ movie.release_date }}</td>
            <td></td>
        </tr>
    {% endfor %}
</table>
{% endblock %}

And now try to browse http://localhost:8000 you will see:

Result

It looks great. Now we will implement CreateView class.

5. Create Movie

To implement create movie function, we can choose between multiple approaches, but I just try the easiest approach, is to create a view class that inherits from django.views.generic.CreateView class.

Firstly, we need to create create.html template:

{% extends "base_page.html" %}

{% block title %}Create Movie{% endblock %}

{% block content %}
<h1>Create Movie</h1>
<form method="post" class="form">
    {% csrf_token %}
    {% for field in form %}
        <div class="form-group">
        {{ field.errors }}
        {{ field.label_tag }}
        {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Submit" />
</form>
{% endblock %}   

By inherits CreateView, it’s very to implement our CreateView:

from django.views.generic import CreateView
from MovieLib.models import Movie

class CreateView(CreateView):
    template_name = 'create.html'
    model = Movie
    success_url = '/'

, And add into the MovieLib/urls.py:

from django.conf.urls import patterns, url
from MovieLib import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view()),
    url(r'^create$', views.CreateView.as_view()), #new line
)

Just some simple lines of code, you’re done for movie creation feature. Let try to browse http://localhost:8000/create and add some new movies. Our CreateView class will handle both GET and POST request. The validation rules defined in Movie model are used to validate user input but no error message was showed, I will have another article for validation topic.

6. Update Movie

To create update movie fuction, we need to create a new view inherits from django.views.generic.UpdateView:

class UpdateView(UpdateView):
    template_name = 'update.html'
    model = Movie
    success_url = '/'

Then, we need to create update.html template:

{% extends "base_page.html" %}

{% block title %}Update Movie{% endblock %}

{% block content %}
<h1>Update Movie</h1>
<form method="post" class="form">
    {% csrf_token %}
    {% for field in form %}
        <div class="form-group">
        {{ field.errors }}
        {{ field.label_tag }}
        {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Submit" />
</form>
{% endblock %}

Add new URL to MovieLib\urls.py:

url(r'^edit/(?P<pk>\d+)$', views.UpdateView.as_view(), name='movie_edit'),

Add a new Edit link for each Movie item in index.html template:

<a href="{% url 'movie_edit' movie.id %}" class="btn">Edit</a>

7. Delete Moview

Create a new class called MovieMixin in MovieLib/forms.py:

from MovieLib.models import Movie

class MovieMixin(object):
    model = Movie
    def get_context_data(self, **kwargs):
        kwargs.update({'object_name':'Movie'})
        return kwargs

Then a new view inherits from django.views.generic.DeleteView:

class DeleteView(MovieMixin, DeleteView):
    template_name = 'delete_confirm.html'
    def get_success_url(self):
        return reverse('movie_index')

Add new URL to MovieLib\urls.py:

url(r'^delete/(?P<pk>\d+)$', views.DeleteView.as_view(), name='movie_delete'),

Add new delete link to each Movie item in index.html template:

<a href="{% url 'movie_delete' movie.id %}" class="btn">Delete</a>

8. Update create and index links on base_template.html

<li><a href="{% url 'movie_index' %}">Index</a></li>
<li><a href="{% url 'movie_create' %}">Create</a></li>

8. Conclusion

As a new bie of Python and Django, I just try to get thing done, that is the reason why I do not explain the reason why I use this class or that class, or the mechanism inside of django. I just try to make a CRUD app that works, and it really works. Hope that you can follow a make a new version of your own.

If you want copy my source code for reference, you can clone on my GitHub:

My choices: Python/Django, Groovy/Grails and Java

It’ve been 7 months from my last post on tumivn.com. In the last post, I share with everyone that I will take my free time to focus on Java. Yes, in the last 7 months, I spent all my free time to learn/re-visit Java, Spring MVC, Scala, Laravel, Python.. to find the best match languages and frameworks to me.

Spring MVC is not for me

Learning Spring MVC makes me exited but also take me a lot of time. It’s not as easy as learning ASP.NET MVC or Laravel. Spring MVC required a lot of configurations to make it works and It’s not the good solution for rapid web development. PHP guys and RoR guys will be extremelly angry when working with Spring MVC. For me, I’m not angry, but I’m confused why it needs to be so complicated. The first Spring MVC project that I worked with is in 2009, and it’s about 5 years from that time, and the complexity is still high.

Several weeks in learning Scala

Scala is a beautiful and powerful language, but after spending several weeks playing with Scala, I found out that we can’t easily build up a Scala team in a short period of time. Scala is very hard to master, and it’s very hard to get all your team on the same page.

Play for Java is a better choice when comparing with Spring MVC. I will build some POC with Play in near future. However, I don’t want to just end my journey with just Java, Scala and PHP. I want to play more with another language, and it’s Python.

One week with Python/Django

Python rocks! Python and Django simplicity make me wanna cry, I want to work with high productivty language and framewor like Python and Django. Their readability really impresses me. I’m really in love of Python and Django.

..and change the plan

And now, I have to change the plan. As an .NET technical architect, I still update my .NET/ASP.NET/SQL Server/BizTalk.. knowledge, I still conduct .NET/TDD/ASP.NET MVC courses for my company. I also put Python/Django, Groovy/Grails and Java into my plan:

  • Rebuild my blog (tumivn.com and vn.tumivn.com) by using Django to learn more about Python/Django.
  • Rebuild Jou.vn developer community using Python/Django + some Java services as well.
  • Write articles about: Django, Play Framework, Groovy/Grails for Vietnamese developers.

Thanks Python & Django, you make me want to code again. Being a manager/TA is good, but I still love programming.

Coding for happiness! ^^

Back to my developer life

Spring Boot

I’m familiar with .NET Framework and ASP.NET MVC, I did love ASP.NET MVC over Spring 2 because of its simplicity, and it was the reason that I chose .NET and ASP.NET MVC for my first startup company in the year of 2009.

Now, I’m not an entrepreneur, I’m just an employee, a technical architect in an outsourcing company and I’ve lost my habit of programming like a developer.

And when thinking of a create anything related to community, ASP.NET MVC is not my 1st choice anymore, although ASP.NET MVC is open source and free, but IIS and Windows Server is not free, and I had to pay a lot when running the Jou Developers community (a community for Vietnamese developer).

I turned to PHP and Java, but my feeling about PHP is that it’s not the language I love the best, Laravel is great, NginX is great, but I’m not in love with PHP anyway. Java is something different, I like Java, but I’m afraid of XML stuff, and I hate to configure everything by myself for a small web application. This is also the reason why I do not like Android very much, when I have to touch XML files every time.

New Spring, Spring Web MVC, Spring Boot, thymeleaf and Gradle really wake me up. I can write web application or console Java application without fear. They save my time. Especially Spring Boot, with it, we can simple call a java command to run a website without any pre-install webserver. ASP.NET is changing with OWIN and Katana, but it doesn’t mean that we will have a light weight web server instead of IIS to host a website. XPS server of Mono is good but not up-to-date, it’s very hard to configure and I give up using XPS. Why I have to waste my time when I have Apache, Tomcat, Nginx, and Jetty.

I’m a .NET technical architect, and I’m still a .NET developer. But by now, most of my personal projects will be developed by using something that are more open like Java, Scala, JavaScript and PHP.

This blog has been idle for a long time, now it’s the time to make it rise again. Back to my hobbies, I will reading-coding-writing night and day. Saigon, 24/02/2014

Getting started with Spring MVC and Gradle

Today, I would like to share an article that can help to get started with Spring MVC and Gradle.

What is Gradle?

I never use Gradle before, however, it’s easy to know what Gradle is, due to wikipedia.org:

“Gradle is a project automation tool that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based DSL instead of the more traditional XML form of declaring the project configuration.”

I don’t know about Groovy, however, we can learn a lot about Gradle by visiting http://www.gradle.org/.

Install Gradle on Windows

Download the latest Gradle distributed package at http://www.gradle.org/. Current version of Gradle is 1.9.

I extract Gradle distribution to folder c:\gradle-1.9 and also add gradle root folder to system PATH variable.

To see as if Gradle is working, open command line application and try to call gradle.bat, the you see the result like below, you can now using Gradle.

I choose NetBeans 7.3 to be my IDE, but NetBeans doesn’t support Gradle officially, so we need to install a plugin named Gradle by follow the instruction from the web page http://plugins.netbeans.org/plugin/44510/gradle-support.

After installing Gradle, you need to configure Gradle plugin by open menu Tools->Options. We need to set the Gradle Installation Directory for the plugin.

Then, use NetBeans to create new Gradle project:

After choosing project type, now we have to input project name and the main class:

After clicking finish, then a project will be created with its structure like below:

You can see the build.gradle file and settings.gradle file. The build.gradle file is the most important one. You don’t need to use NetBeans to create the project, you just need create a new folder and create the two files build.gradle and settings.gradle.

The settings.gradle just contains the project name:

rootProject.name = 'gradle-simple-mvc'

The build.gradle stores all configuration needed for our project:

apply plugin: 'java'

sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    ext.mainClass = 'com.tumivn.mvcsample.Main'
}

repositories {
    mavenCentral()
}

dependencies {
    // TODO: Add dependencies here ...
    // You can read more about how to add dependency here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

To enable java in the project, we need to enable java plugin:

apply plugin: 'java'

The main repository we use for loading dependencies (java libraries) is Maven so we need to declare it:

repositories {
    mavenCentral()
}

Netbeans also declare a dependency for the project, which is JUnit, for unit testing:

dependencies {
    // TODO: Add dependencies here ...
    // You can read more about how to add dependency here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

However, we need to change the the content of the build.grade so it will be a Spring MVC application other than a Java SE application:

apply plugin: 'war'
apply plugin: 'jetty'

repositories {
    mavenCentral()
}

dependencies {
    providedCompile 'javax.servlet:servlet-api:2.5'
    compile 'org.springframework:spring-webmvc:3.2.5.RELEASE'
    testCompile 'junit:junit:[4,)'
    runtime 'javax.servlet:jstl:1.2'
}

/* Change context path (base url). otherwise defaults to name of project */
jettyRunWar.contextPath = ''

We need 'war' plugin to enable web development and when building the application a war file will be created for deployment; 'jetty' plugin for running jetty web server and deploy our website for testing. And the project need more dependencies:

dependencies {
    providedCompile 'javax.servlet:servlet-api:2.5'
    compile 'org.springframework:spring-webmvc:3.2.5.RELEASE'
    testCompile 'junit:junit:[4,)'
    runtime 'javax.servlet:jstl:1.2'
}

We need javax.servlet:servlet-api version 2.5 and spring web MVC framework version 3.2.5 for develop our website.

Then, we need add more folders to create web application structure:

You can see the web.xml file, it's the web configuration file, below is its content:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

in this file we need to declare an org.springframework.web.servlet.DispatcherServletDispatcherServlet instance to processing work flow. Its name is dispatcher and the configuration file will be stored at [application root]/src/webapp/WEB-INF/spring/dispatcher-servlet.xml.

The dispatcher-servlet.xml content:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
            http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.2.xsd">

  <context:component-scan base-package="com.tumivn.mvcsample.controller" />  
  <mvc:annotation-driven />

  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/view/"/>
    <property name="suffix" value=".jsp"/>
  </bean>

</beans>

We declare to use annotation to configure routing instead of using XML by a declaration:

  <mvc:annotation-driven />

Beside, we have a declaration to allow dispatcher-servlet to scan through com.tumivn.mvcsample.controller package to get controllers appropriate for each request.

Now it's the time to write the first controller named HomeController:

package com.tumivn.mvcsample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

    @RequestMapping("/")
    public String loadIndexPage(Model model) {
        model.addAttribute("title", "Hello Spring MVC!");
        return "index";
    }
}

The loadIndexPage method is configured to response to the "/" request, and it will send the model with "title" message inside and the view "index" (WEF-INF/view/index.jsp) to front controller to merge view and model and return the result to browser. Below is the implementation of index.jsp

<!DOCTYPE HTML>
<html>
    <head>
        <title>${title}</title>
    </head>
    <body>
        <h1>${title}</h1>
    </body>
</html>

Now, it's the time to build the application. You can easily right click at the project root and choose build menu to build. Or open command line and go to the project root folder and then call "gladle.bat build" command and see build successes.

Now, it's time to run the web application by using the jettyRun task of gradle.

The Jetty server will be run and the website will be available at address http://localhost:8080/gradle-simple-mvc. Open a browser and browse the url and you will see a message "Hello Spring MVC!" on the browse. Congratulation!

To reference, source code is available at GitHub.

This is the first time I touch Java for 5 years. Many things new, and many things I almost forgot. But Java, Gradle and Spring MVC make me excited. I love to learn more about Java and PHP for my personal projects. And still use .NET and ASP.NET MVC for daily jobs.

Happy coding!

The beginning of a software scraftsman

Carpenter

When I’m as the 1st year of university, it took me 6 months to read a Visual Basic book.

After graduated, I realize that I can read a technical books in just a week.

At 22 years old, I became a lecture.

Then, when I was 24, I realized that reading book only can’t make me a pro, I needed more practicing

I became a Java developer for a software company at Hue city.

When I was 26, after a year of building my first framework for ASP.NET MVC, I realized that I need more experiences from real-world software company. At the same time, I realize the value of knowledge sharing, I wrote articles, celebrated code camps, trained the students about new technologies.

In 2010, when I was 28, I became a Microsoft Most Valuable Professional. At the same time, I went to Ho Chi Minh city and start my career as training manager, and after a year working as a training manager, I realized that couldn’t be a good trainer without more experiences.

At the beginning of 2012, I became an technical architect for a start-up company. Building development team, delivering proposal, a half-project manager.

In the middle of 2012, when bidding a big enterprise project, I realized that I didn’t know anything about enterprise. Self-practicing and reading didn’t make me a real software architect.

In the end of 2012, I joined a big software outsourcing company as Technical Architect.

At this time, at the age of 30, I realize that, to be a Technical Architect / Software Architect, I need to read and practice more and more. Broad technical view, hands-on experience, best practices, domain knowledge and the ability to learn and apply every technical with light speed is the key words for my next success.

But don’t forget to learn about data structure and algorithms, strengthen OOP design skills, learn more about database design and programming, the heart of software is data.

Don’t forget to write more articles, tutorials, and build more open source.

Don’t forget to respect people that share their knowledge to you.

Don’t forget to optimize your way of learning and practicing.

Now, it’s just a beginning of a road, the beginning of a software developer!

Tumi learns PHP – 02 – Apply unit testing to Harmonic series calculation

It’s been a while when I write the first article of Tumi learn PHP series. Today, I will refactor it a little bit by applying OOP and Unit Testing to make sure Harmonic calculation is more accurate and easier to maintain.

First thing first, I will change the website folder structure:

  • “app” folder is for storing application code
  • “public” folder is for storing web page, HTML and CSS, they are visible to end users
  • “tests” folder is for storing unit tests
  • “vendor” is for storing 3rd party libraries, e.g. PHP Unit

The virtual host points to “public” folder.

Now, we will use composer, a package manager for PHP project. We will go to http://getcomposer.org/ to visit Composer home page and go to download page to download composer.phar archive and put to any folder that you want on your local machine. For me, I will put the composer.phar to application root folder.

At the root folder of our application we will create a composer.json file to declare what 3rd party libraries that we will use and then use composer to get them for our project.

{
    "require-dev": {
        "phpunit/phpunit": "3.7.*"
    }
}

Open command line and navigate to our project root folder and call:

php composer.phar install

You will see something like the below screen shot:

Composer install

And the folder structure is:

Website folder structure

I use NetBeans as an IDE for this project so there will be a nbproject folder inside the application folder, but you can use any editor you want. And we will see that composer download phpunit and some symphony class for us. Because phpunit is dependent on some symphony classes, so composer will download the dependencies as well.

Now, we create a class Harmonic.class.php inside ~\app folder, it is for store the maximum number of Harmonic series and have a total() method to calculate the total of its series.

<?php

class Harmonic {
    private $maxNumber;

    function __construct($n) {
        $this->maxNumber = $n;
    }

    function total() {
        //TBD
        throw new Exception('Not implemented');
    }
}

The total method is not defined yet. We will implement it by following the TDD (Test Driven Development) process, it means that we will follow the red – green – refactor process. We will create test first, run it and see it fail, modify our class to pass the test, refactor it, then write another unit test and continue to test to see it fail…

Create a PHP file called HarmonicTest.php inside “tests” folder:

<?php

include_once '../app/Harmonic.class.php';

class HarmonicTest extends PHPUnit_Framework_TestCase
{
}

The Harmonic Test class will store all unit tests for Harmonic class and it’s derived from PHPUnit_Framework_TestCase class.

Now we implement the first unit test as a method of Harmonic test class to test the simplest case; the Harmonic class can calculate the series with max value is 1.

public function testTotalIsCorrectWithMaxValue1()
{
    $harmonic = new Harmonic(1);
    $total = $harmonic->total();
    $this->assertEquals(1, $total);
}

Now, we will try to run the test by invoking phpunit.php class like below:

First unit test

Yes, the test failed, because we didn’t implement the source code. To simply pass the test, I modify the total method to return maximum value:

function total() {
    return $this->maxNumber;;
}

Run the unit test again and see it passes. Now, we write unit test for another test case (maximum = 3):

public function testToalIsCorrectWithMaxValue3(){
    $harmonic = new Harmonic(3);
    $total = $harmonic->total();
    $this->assertEquals(1 + 1/2 +1/3, $total);  
}

Run unit tests and we will see the above unit test fails:

Second unit test

Now we have to modify the total() method of Harmonic class:

function total() {
    $result = 0;
    for ($i = 1; $i <= $this->maxNumber; $i++) {
        $result += 1 / $i;
    }
    return $result;
}

Run unit tests again, we will see all test pass.

Are we done? No, not yet. Please don’t forget the sad paths. When the parameter is not as we want, e.g. $maxNumber is not a number, or $maxNumber is less than 1. When $maxNumber is less than 1 we simple return a null value.

When $maxNumber is not an integer, we expect that an InvalidArgumentException is throwed:

    /**
    * @expectedException InvalidArgumentException
    */
    public function testTotalWhenConstructorParameterIsNotInt(){
        $harmonic = new Harmonic("Is String");
        $harmonic->total();
    }

We need to learn more about PHPUnit to use it well. After Red status, we should implement Hamornic constructor as below:

function __construct($n) {
    if(!is_int($n))
        throw new InvalidArgumentException(
                'Only accepts integer');
    $this->maxNumber = $n;
}

Maybe this will be enough and now we update our code to use Harmonic class. As mentioned above, the harmonicseries.php will be stored at public folder so end user can access:

harmonicseries.php

And the harmonicseries.php is modified:

<?php
include_once "../app/Harmonic.class.php";
/* Write a PHP app that, which sums the terms of the harmonic series 
(1 + 1/2 + 1/3 + 1/4...) up to a limit supplied by the user.
*/
$method = $_SERVER['REQUEST_METHOD'];
$message = '';
$hasTotal = false;

if('POST' == $method)
{
        $limitNumberString = $_POST['limitNumber'];     
        if(is_numeric($limitNumberString)){
            $limitNumber = intval($limitNumberString);
            $harmonic = new Harmonic($limitNumber);
            $total = $harmonic->total();
            $message = "Total (with n = " . $limitNumber . " ): " . $total;
            $hasTotal = true;
        }else{
            $message = "Error! You didn't input a number!";
        }
}

?>

<html>
    <head>
        <title>Harmonic series sum</title>
        <style type="text/css">
        .hide{
            display: none;
        }
        </style>
    </head>
    <body>
        <div <?php  echo($hasTotal?'class="hide"':""); ?>>
            <form method="POST">
                <p><label>Enter N to evaluate 1 + 1/1 + 1/2 + 1/3 + ... + 1/(n-1) + 1/n: </label></p>
                <p><input type="text" id="limitNumber" name="limitNumber" /></p>
                <p><input type="submit" value="Submit" /></p>
            </form>
        </div>
        <div>
            <h3><?php echo $message; ?></h3>
            <?php  echo($hasTotal?'<a href="">Calculate with another value of N..</a>':""); ?>
        </div>
    </body>
</html>

Yes, it work well, but again, it now well tested. The harmonicseries.php still contain logic, and it is tested. We need to apply a pattern like MVC to apply more unit test for our code. In the next article I will introduce a MVC Framework called Laravel and we will try to implement a website with CRUD features and access to a database (MySQL / SQLite).

You can find the source code on GitHub.

Happy coding!

Which JavaScript MVC Framework should i use?

Popular JavaScript MVC Frameworks

Which JavaScript MVC library should we use?

It’s hard to make decision because a lot of JavaScript MVC framework out there. For outsourcing business, it depends on what customer want. For personal usage, we can think read comparison articles and choose what we want.

Here’re two great links for your reference:

http://coding.smashingmagazine.com/2012/07/27/journey-through-the-javascript-mvc-jungle/

http://www.infoq.com/research/top-javascript-mvc-frameworks

http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/

Back to Java world

Back to Java world

I remember of the day I gave up my job as a teacher at College of sciences and I had been interviewed to be a Java developer. The interviewer asked me many things about Java and HTTP, and I didn’t know anything at all. But, luckily, I passed and became an Java Developer.

In just nine months, I’d learned a lot about Java, JSP, EJB, Hibernate and many things more. But the company went to trouble with finance, and all developers lost their job including mine. The time being a Java developer is quite short, but It changed me from the one who didn’t know anything about how to make a real software became the real developer, who can build his own software, who can learn any technology for development without fear.

I’ve learnt .NET, JavaScript, PHP.. by myself and founded a small IT company that build softwares and websites by using .NET and ASP.NET MVC. And by now, I’m a .NET Architect, and has a programming blog, a .NET community for Vietnamese founded and programmed by me myself.

I decided to learn more about programming world by learning PHP, NodeJS… However, in the last two days, I’d lived alone and thinking about all the stuffs that I did before. I realize that Java bring me the passion of a programmer. Programming Java make me know about MVC, ORM, DDD and more. Java is pure OOP like C#, and Java world is huge (with/without Android). I’m eager to learn more about Java, Java EE, Apache Open Source and Linux.

I’ve learned PHP, and I keep on using it. But for my career a path, as a Software Architect, I need to a more powerful tool like Java and .NET. So it is the time to push the Reset button and re-build my knowledge to make it solid and make me more ready for enterprise world.

That means, I will not write a lot of articles for Vietnamese developers as usual. I will find a new administrator and a small team that will work on Jou Developers source code to enhance it.

I need to train myself and step up to a new level. I want me to be more ready as an Technical Architect. And have strong software development skill with Java and .NET.

I still love to learn more and more programming languages in my free time but from now I will focus more on enterprise software development.

Tumi learns PHP – 01 – Calculate the Harmonic series

I’ve spent a lot of my time to learn PHP without coding. It’s a shame. I believed that I can remember PHP syntax easily because I have 7+ years of C#. I also learned C++, VB6, VB.NET, ActionScript, Java and JavaScript before. But, the truth is, I can’t remember anything about PHP after learning it.

A friend of mine replied of Twitter when I said “Read programming books everyday”, he said “don’t forget to code as well”. Yes, you can’t be a senior guy without practicing. You can tell everyone what PHP has, what is Zend, what is Laravel, how they’re compared together, but when you try do real thing, you will be confused. So, I decide change my way in learning PHP, and I will share to you.

This is the first article of the series “Tumi learns PHP”. But please consider:

  • You can’t learn everything about PHP by reading my article. It’s just my way in practicing PHP.
  • You should skim through some PHP fundamentals book to learn PHP syntax or visit http://www.w3schools.com/php/ to learn.
  • I’m Vietnamese, English is my 2nd language, and it means that I can have a lot of typo/grammar mistakes. So please correct me if anything wrong.
  • And the most important one, I’m just a PHP newbie, please help to make me a better PHP programmer.

Problem

Write a web app which sums the terms of the harmonic series 1 + 1/2 + 1/3 + 1/4… + 1/(n-1) + 1/n  up to a limit supplied by the user. (n > 0, n is an integer)

My Questions

Currently I do not have any idea at all. But I have questions:

  • What is PHP, anyway?
  • Yes, I know PHP is a language for web development, I need an editor for writing PHP code, and which editor should I use?
  • I know that code can run by itself, it need to be compiled, how to compile PHP code and deploy it so that we can use it?
  • Environment for PHP development? How we setup that?

What is PHP?

WikiPedia.org define: “PHP is a server-side scripting language designed for web development but also used as a general-purpose programming language.” and “PHP code is interpreted by a web server with a PHP processor module, which generates the resulting web page: PHP commands can be embedded directly into an HTML source document rather than calling an external file to process data. It has also evolved to include a command-line interface capability and can be used in standalone graphical applications.”

PHP is a server-side scripting language and it’s also an interpreted language. It means that, PHP doesn’t need to be compiled before like Java, C# or C++, it is parsed and performed directly by an interpreter at runtime.

How can I develop web app with PHP?

It’s quite easy to getting started with PHP. I will introduce of how to install PHP on Windows first. At the moment, I just want to have PHP install on my computer, and can write some PHP code as soon as possible. I have heard about:

  • WAMP (Windows – Apache – MySQL – PHP)
  • LAMP (Linux – Apache – MySQL – PHP)
  • MAMP (Mac OS – Apache – MySQL – PHP)
  • Or NginX ( a web server that support PHP)

Apache is a well-known web server for PHP, it is open source like PHP and it’s free. MySQL is a database management system, is also an open source. We will learn about them in later articles.

Right now, we go to http://windows.php.net/download/, my computer is a Windows 8 x64 one, so I choose PHP 5.5.3 VC11 x64 Non Thread Safe (php-5.5.3-nts-Win32-VC11-x64.zip). I download it and unzip it at E:\PHP\ (you can extract anywhere you want to).

Now open the Command Line (or PowerShell), and try to check PHP version:

Figure 1.1: Check PHP versionFigure 1.1: Check PHP version

On the above screenshot, I use the –V parameter to see installed PHP version, it is 5.5.3.

Ok, we already have PHP inside our computer, but how to start programming with it?

Don’t worry, first thing first you should add your PHP directory in to PATH variable of Windows, then you can call PHP everywhere you want. Follow this guide (http://www.computerhope.com/issues/ch000549.htm) to add PHP to Windows PATH variable.

Now, we use PHP.exe command to print the result of 5 + 3:

Figure 1.2 – First PHP sentence Figure 1.2 – First PHP sentence

You can see the command and its result in figure 1.2. However, PHP is for web development, how can we do it without Apache or Nginx? Luckily, PHP has a built-in web server, and you can host your website for study purpose without installing Apache or NginX.

Create a folder that will contain you PHP files (I choose E:\_Websites\ex_01). Inside that folder, create hello.php, by call the below command:

Figure 1.3 – Create hello.php

Figure 1.3 – Create hello.php

Then type the content for hello.php using Notepad.

Listing 1.1 – Hello.php On the above code, the hello.php includes PHP code and HTML code, and PHP code is wrap inside <?php .. ?>. Now, back to the command line, and host the ex_01 folder as a website by using PHP built-in server: Figure 1.4 – Host a website using PHP built-in server Figure 1.4 – Host a website using PHP built-in server Now open your browse and navigate to http://localhost:8089/hello.php Figure 1.4 – My first PHP web page Figure 1.5 – My first PHP web page   So, we have our first PHP page, but writing PHP code with Notepad program is not a good idea. You need a more powerful editor that has PHP color syntax, code auto completion and much more. I prefer to choose Sublime Text, but Notepad++ is good as well. And there are many more powerful editor that support PHP like NetBeans, Eclipse…,  most of them are free.

Solving problem

Now we back to the problem that we write out in the beginning of the article “Write a web app which sums the terms of the harmonic series 1 + 1/2 + 1/3 + 1/4… + 1/(n-1) + 1/n  up to a limit supplied by the user. (n > 0, n is an integer)” In the root folder of the website, I create a PHP file called harmonicseries.php, we will implement our code to solve the problem inside it. Let consider the situation:

      • User will request the address http://localhost:8089/harmonicseries.php, and will get a web page that show a text box and a submit button; user will input the value of n and click submit button to send n value to web server.

 

  • The web server will calculate the harmonic series total and send back the result to end user.

 

Let start coding! Now we add some HTML code into the file:

Listing 1.2 – HTML form for inputting the value of N

When try to browse, we will get a web page like below:

Figure 1.5 – The harmonicseries.php UI

Figure 1.6 – The harmonicseries.php UI

You can click on Submit button, but nothing happen because there is no server side code for processing it.

When you try to browse http://localhost:8089/harmonicseries.php, you‘ve just created a GET request to server and web server parse PHP code and generate HTML content and return back to the browser. Then, you input the value of N to the textbox, and click Submit button. The browser will send a POST request to web server when Submit is clicked. This is because we set the method of HTML form to POST. When receiving the POST request, we need to have PHP code to retrieve the value of N and calculate the total number and then return the result back to client.

To determine if a request is POST or GET, you need to access a global variable $_SERVER like below:

Listing 1.3 – Detect request method

After thinking for a while, I decide to implement the entire code like below listing:
Listing 1.4 – Implement the harmonicseries.php

if you’re new to web development, you will have many questions for the above code. But I do not explain anything. You should try and to answer by yourself.

Now try to run the web page, and enter an invalid value to the textbox and click Submit:

Figure 1.6 – Try to add an invalid value

Figure 1.7 – Try to add an invalid value

You will receive the error message:

Figure 1.8 – Result when sending an invalid value to web server

Figure 1.8 – Result when sending an invalid value to web server

When you enter an valid value, you will receive the result:

Figure 1.9 : Result when sending a valid value to web server

Figure 1.9 : Result when sending a valid value to web server

Congratulation, you’ve done it.

Anyway, the above code is not good enough, and as an experience .NET developer, I ask myself how to improve the code, because:

  • This code is not easy for unit test, and how to unit test with PHP?
  • This code is not well designed, maybe we should apply some OOP principles.
  • Validation is not well enough, some invalid case is not checked, e.g. user enter decimal/negative value.

And I decide to learn how to make my code better by applying unit test and redesign the existing code in the next article.