Archive for February, 2010

Java Rant #1

Once apon a time, I to some extent spent time learning Java. It was not a lot of Java, and it wasn’t extremely indepth. It was more of a “get to know the language”; doing some simple database hits, very basic console and windows app. This was all back in 2000-2001 so much has changed since then. I have since learnt and worked with c#, Python, Ruby and have for the most part been happy with what these languages bring to the table.

In recent days I have been contemplating over working on a few personal projects, some being “desktop apps” and others being web apps. Normally I would have written any desktop apps with C#, but with my recent migration away from just windows I feel it might be a good time to give Java another chance.

It seems a lot of the things I really wasn’t a fan of are still there today, things that other languages have been able to overcome several years ago and Java still can’t seem to handle.

Properties
Why is it that a language as “young” as C# not only has been able to handle properties in a nice way but they have also been able to change it a second time allowing for “automatic” generation of “basic” properties…

Simple “Person” Class in C#


public class Person {
 public string Name { get; set; }
 public string Email { get; set; }
}

Similar class in Java.


public class Person {
  protected String name;
  protected String email;

  public String getName() {
   return name;
  }
  public String getEmail() {
   return email;
  }
  public void setName(String value) {
   name = value;
  }
  public void setEmail(String value) {
   email = value;
  }
}

I guess you could expose the values in Java as protected to be public and change them directly, But if you need to make a change down the road where you need to add some sort of validation or something to these values, your left to putting it outside of the class that is responsible for the properties.

I am not turning away from Java, but I would think after so many years and so many implementations in other languages that something would have been implemented. Unless there is some hidden command I have not been able to find online or in documenation.

Django ModelForms With Foreign Keys

I have recently been working more and more with django forms. In previous projects we decided not to use them mostly cause we couldn’t get them to do what we wanted them to do. In retrospect it was more of a lack of understanding how they worked and insufficient time to sit down and learn them.

Earlier in the week I was working with a model based form with a foreign key to another model. Problem I ran across was that I wanted said form to be displayed on the page, and also post the proper foreign key id without the user selecting it ( foreign keys are selected through a select box which can get quite large ). The page in which this form would be displayed would always know the foreign key id, so there would never need to be a situation where the form would ever need to show the user a select box.

After much trial and error, here is what I came up with.


from django.forms import ModelForm
from django import forms
from models import Thread
from models import Post

class ThreadForm(ModelForm):
    class Meta:
        model = Thread
        fields = ('Message', 'user')

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ( 'Message', 'user')

The Post in question would normally have a foreign key in this instance to Thread, but we exclude it from the form so that it is not validated against or displayed to the user.


    <form action="/post/{{ thread.pk }}/" method="post">
        {{ form.as_p }}
        <input type="submit" value="Submit" />
    </form>

In the actual form posting we are using the threads key in the url that is receiving the new post, If you were not using in the url, you could simple just add it as a hidden value on the page.


def post_add(request, thread_id):
    a_form = PostForm(request.POST)

    if(a_form.is_valid()):
        post = a_form.save(commit=False)
        post.thread_id = thread_id
        post.save() 

In the post_add view which accepts the thread_id and passes it to the method, we create the form based on the post data. validate it and save it. By adding the commit=False we stop the Form from saving the data to the database. and we return a model object. Which we can then pass along the thread_id and save it.

Their are a few things that could be added to the view for extra checking. We could do a lookup for a thread id and make sure its there, and do checks for request.method, or even add in handling for ajax requests. The example view isn’t complete and is only there as a quick sample of how to handle these types of forms.

Mobile Site Redirection

In recent years a major component for any popular site is to add some sort of mobile experience. By adding a mobile aspect of your site either in full or in part, you open it up to even more people. In the last few years as mobile phones have become more powerful and less money. Having a mobile phone that is capable of viewing a full sized normal webpage isn’t as heard of now as it was just a few years ago.

With phones being capable of viewing sites in full and as mobile markup, it can sometimes be harder to present the user with the experience they are looking for. Simply using the user agent can help but it doesn’t give a full indication if the user has there browser setup as full or mobile. There is another way that can be used to some extent and works on any phone with a properly implemented browser.

HTTP_ACCEPT, is a header that is sent from the browser to the server when requesting resources. Contained in this header is a description of what the browser is capable of accepting or is willing to accept. Using this header it is possible to help determine if the user is on a mobile phone viewing in “mobile mode” or as a full browser. By checking for “application/vnd.wap.xhtml+xml” you can be assured that the user is viewing the site on a “mobile” browser.


from django.http import HttpResponseRedirect
from django.conf import settings

class MobileMiddleware(object):
  def process_request(self, request):
    try:
      if(request.META.get('HTTP_ACCEPT', '').find("application/vnd.wap.xhtml+xml") >= 0):
        return HttpResponseRedirect(settings.MOBILE_SITE)
    except:
      pass
    return None

Setting this up as a middleware in your settings file, as well as adding a new directive in your settings file such as:

Settings.py


MOBILE_SITE = "http://m.domain.com/"

This will allow you to simple redirect users on viewing the site as “mobile” to be redirected to the mobile site. A couple things to keep in mind though. If you are using the same code and just using different templates for the main site and the mobile site, you will want to add in logic to make sure you don’t hit a continous loop. Since not all browers are written to full standard, this isn’t 100%, but nothing is this will just help in giving users a more seamless user experience.

Django Json Woes

Recently I have been working on a new web project, written in Python using the Django web framework. I have been using Django off and on over the last year, traditionally I really never used much of a framework. A great deal of my time prior to Python/Django work was spent on applications development for server side processes written in C#.

I have a strange love/hate relationship with python, I love some of its capabilities, ease of use, and its concise nature. On the other hand I hate that there seems to be some things that I would love to see that just isn’t there. While writing a simple view in which I planned on returning a JSON string back to the user, I found there was no “response” or internal method that I could find to return it simply. In the process of going through the documentation I found some information relating to the HttpResponse that gets returned at the end of each View. I figured that would be a great place to start.


from django.http import HttpResponse
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200):
    HttpResponse.__init__(self, content = encode(data), mimetype = 'application/json', status = status)

First revision looked something like this. At first it worked out doing what I had wanted, one problem I had was while using a mime type of ‘application/json’ was more secure it made debugging a little more difficult when hitting the view directly in the browser. So I figured if I was running in debug why not use a mime type of ‘text/html’, its less secure but debug should never run on production.


from django.http import HttpResponse
from django.conf import settings
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200):
    mimetype = 'application/json'

    if(settings.DEBUG):
      mimetype = 'text/html'

    HttpResponse.__init__(self, content = encode(data), mimetype = mimetype, status = status)

This revision looked much more what I needed. The only problem I had was when hitting this view from Javascript on the client side, some browsers would cache the return value and an additional hit to the view wouldn’t occur. I could have solved this on the client side by adding some sort of random seed to the end of the URL. However I would much prefer my view decide when something needs to be cached rather than the JavaScript code so I made a few modifications.


from django.http import HttpResponse
from django.conf import settings
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200, cache = False):
    mimetype = 'application/json'

    if(settings.DEBUG):
      mimetype = 'text/html'

    HttpResponse.__init__(self, content = encode(data), mimetype = mimetype, status = status)

    if(cache == False):
      self['Last-Modified'] = 'Mon, 01 Jan 1970 05:00:00 GMT'
      self['Cache-Control'] = 'no-store, no-cache, must-revalidate'
      self['Pragma'] = 'no-cache'

Making this change allowed me to have the flexibility of deciding if I wanted something cached, which in most instances I don’t since the data for these returns are normally always changing. With this new object I was able to perform a “standard” JSON return in a view as well as maintain a single place I can make modifications to all requests at once.


from responses import JsonResponse

def json_view(request):
  x = { 'status': True, 'message': 'Success' }
  return JsonResponse(x)