Categories: , ,
Posted by: bjb
I created a django project and application and the associated database. I created the tables with syncdb over a couple of development iterations. I can still run ./manage.py syncdb in the original project with no output. I tried copying the project to another directory, creating a new (empty) database (db-dev) and adjusting the settings.py in the new project. When I run ./manage.py syncdb in the new project, it says:
psycopg2.ProgrammingError: relation "fileshare_language" does not exist
Shouldn’t django create the relation (table) as part of the syncdb operation? models.py:
    class Language (models.Model):
        '''
        Class to represent the choice of languages available so far
        '''
        language = models.CharField (max_length = LANGUAGE_LEN)
    
        def __repr__ (self):
            return self.language
    
    
    class Clients (models.Model):
        '''
        Class to represent the clients.  This class is associated
        with the Django User Model (where the name and email address are stored).
        '''
        user = models.ForeignKey (User, unique = True)
    
        filedir = models.CharField (max_length=FILE_PATH_LEN)
        language = models.ForeignKey (Language)

    ...
    
    class AddClientForm (forms.Form):
        '''
        Form for adding a client
    
        Also adds a django user and creates a directory
        '''
        username = forms.CharField (label = ugettext_lazy (u'Username'),
            widget = forms.TextInput (attrs = {'class' : 'form_object_bg' }),
            required = True)
        firstname = forms.CharField (label = ugettext_lazy (u'First Name'),
            widget = forms.TextInput (attrs = {'class' : 'form_object_bg' }))
        lastname = forms.CharField (label = ugettext_lazy (u'Last Name'),
            widget = forms.TextInput (attrs = {'class' : 'form_object_bg' }))
        email = forms.EmailField (label = ugettext_lazy (u'Email'),
            widget = forms.TextInput (attrs = {'class' : 'form_object_bg' }))
        filedir = forms.CharField (label = ugettext_lazy (u'Files Location'),
            required = True)

        language_qs = Language.objects.all ().order_by ('id')
        language_choices = []
        for ll in language_qs:
            language_choices.append ((ll.id, ll.language))
        language = forms.ChoiceField (choices = language_choices,
                                      label = ugettext_lazy (u'Language'))
    
        is_admin = forms.BooleanField (label =
                                       ugettext_lazy (u'Is administrator'),
                                       required = False)
    
        password = forms.CharField (label = ugettext_lazy (u'Password'),
            widget = forms.PasswordInput (attrs = {'class' : 'form_object_bg' }),
            required = True)
        pwd_confirm = forms.CharField (label = ugettext_lazy (u'Password Confirmation'),
            widget = forms.PasswordInput (attrs = {'class' : 'form_object_bg' }),
            required = True)
It turns out that the attempt to put the language choices in a dropdown list in the form is causing syncdb (and every other ./manage.py command) to fail with that traceback. I suppose the quick fix is to create the table and populate it manually in the empty database, and then run syncdb. Later I can fix up the form so it doesn’t have code in the middle of the field declarations. Oops.
Categories: ,
Posted by: bjb

I wrote a small app to allow people to sign up to declare publicly, in a theme-based community, their intention of completing a project by a certain date. It was good practice to learn about django users and authentication and forms.

I wanted to allow the users to sign up and make their own accounts — but obviously I didn’t want them to mistakenly use a username that was already taken. But there is no obvious way to do that in the Django framework. The form validation takes place in a class that does not have access to the request information (where the user id is kept).

Fortunately for me, Ian Ward has already run into that problem and has solved it, both for plain old forms and for modelforms, in a very neat and elegant way.

04/7: byteflow

Categories: , ,
Posted by: bjb

I tried validating (see below) the html on my new(ish) blog — it didn’t validate. It seems the category cloud is non-compliant. But I fixed up the CSS and that validates now.

I will check into the category cloud later.

<a href="/bjb/tag/android/"
title="Click to filter by android"
alt="count: 2"
class="tag-2"
rel="tag">android</a>

<a href="/bjb/tag/apache/"
title="Click to filter by apache"
alt="count: 1"
class="tag-1"
rel="tag">apache</a>

...

The validator doesn’t like “alt” tags on the “a” elements, for starters. The question is, why is it there? Of course it could be commented out (it’s in templates/tagging/tag_cloud.html) but what would break? … Stay tuned.

 continue reading
Categories:
Posted by: bjb

I was trying to integrate django’s user model with my application. I had extended the user with extra data in a UserProfile class, and had made a view require login. The web page was successfully redirected to the login page when visited for the first time, but upon logging in the user was not redirected to the original page. The user was redirected to the /accounts/profile page.

It was because I had not noticed that you had to add something to the login template — you need to add a hidden field called “next” to your login form. Once I added that, and changed the form action to “./?next={{ next }}” it started working correctly.

 continue reading
Categories: , ,
Posted by: bjb

Running django under wsgi wasn’t hard … You make a script called xxx.wsgi, and it has a function called ‘application’ that is the entry point to your application. Django supplies an entry point called @django.core.handlers.wsgi.WSGIHandler()@, so you just have to:

application = django.core.handlers.wsgi.WSGIHandler()

(with a little setup beforehand)

You also should configure Apache to handle the appropriate URL location with mod wsgi:

    WSGIScriptAlias /cp /home/bjb/work/credil-bjb/clientportal/wsgi/clientportal.wsgi

There was a little more stuff so that apache would serve some files statically (what django calls the “media” files and “static” files), but that was standard apache config. The other thing is to enable the wsgi module, and (because I’m using django auth) ensure that all the right modules are loaded and all the wrongs ones are disabled.

I started with this documentation (found a pointer to a parent page in the django docs): http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide

Categories: ,
Posted by: bjb

To get rid of all the data in your database (but keep the tables):

./manage.py flush

That is pretty much equivalent to:

sudo -u postgres dropdb appdb
sudo -u postgres createdb -O me appdb
./manage.py syncdb

I even got asked the questions about creating the superuser after running the ./manage.py flush command.

Categories: ,
Posted by: bjb

Another error made at the same time as the previous one was to call the model constructors with positional args:

mm = MyModel ('name', 'description')

This resulted in creating a MyModel instance like this:

mm.id = 'name' 
mm.name = 'description'
mm.description = None

I should have called them with keyword args so the passed values would be assigned to the right attributes:

mm = MyModel (name = 'name', description = 'description')
Categories: , ,
Posted by: bjb

I made a new django app. First I made a few models, then some unit tests for the models. I could not save newly created model instances in the database, the error was something about there not being an attribute id.

It turned out that although I inherited the models.Model class into each of my models, I was overriding the __init__ function. I should have called super from the derived class’s __init__ method … This is what the model class should have looked like:

from django.db import models

class MyModel (models.Model):

    name = CharField (max_length = 64)
    description = CharField (max_length = 512)

    def __unicode__ (self):
        return self.name

and if i was going to declare an __init__ method, it should have looked like this:

    def __init__(self, *args, **kwargs):
        super(MyClass, self).__init__(self, *args, **kwargs)
        # my own customization code goes here
Categories: , ,
Posted by: bjb

It seems I’m going to be changing some mailing lists for oclug soon. I also ended up offering to help maintain the oclug django code that displays the oclug web site. Yikes! What was I thinking?!? Anyway, it’s written in python/django so at least I’ll be improving in areas I want to improve in. And Ian says he’ll help me out when I need it. Whew.