So my host just started working this morning, so you can see the first stab at the app at http://shipwreck.mibgames.co.uk
I still haven’t quite got the hang of the developer accounts, but I’m persevering with my gmail account, although I would have liked a way to subscribe to the google group with my mibgames account, as I actually read that one daily, whereas gmail I don’t normally make a habit of reading. Although I’ve also apparently managed to get duplicate emails being sent to my personal email address, but haven’t worked out why yet. I’m sure I’ll work it out.
[Edit: Found out why, I had setup my personal account to download email from my gmail account via POP3 ages ago and hadn't turned it off.]
I also had my first couple of weird issues. I had created a django template, called base.html, which defined the base layout (or will do eventually), and was creating a template called create_character.html which inherited from the base template. I defined my title and main blocks in my template, and filled them in, and when I hit the template I got the weird error, TemplateSyntaxError that appeared to say that {% block main %} had a syntax error, and that it couldn’t read the expected next character.
I scratched my head a bit, tried renaming the blocks, tried rewriting it, to make sure I hadn’t done something really stupid. Eventually, I moved the blocks around, moving the title block to the end, and the main block to before the title, and it suddenly started working. Changing it back now doesn’t break it anymore, so I’ve no idea what caused it. Very weird.
My second issue is to do with getting stuff out of the BigTable, but first I had to get something in, and this is where I met my second favourite feature so far. I created a model for the player’s character, containing some basic stats, skills, and admin values. Having created the model, I want to try to be able to create one, save it to the BigTable, and then get it out again.
But the easiest way of creating a character without needing to generate random numbers, and do weird things, is to create a form with all of the relevant fields, and I can manually enter the values, press save and voila, it would save. So I set about creating a Django form for my model object. Having entered the 17 lines of attributes, run a few vim commands to replace db.StringProperty with forms.CharField and stuff, I thought, there must be an easier way than this.
And there is, in google.appengine.ext.db there is a module called djangoforms. Instead of my 17 lines of code, and the hiddeous thought of writing some manual code to hookup the form.clean_data['strength'] to character.strength, you can instead use the following lines of code
from google.appengine.ext.db import djangoforms
class CreateCharacterForm(djangoforms.ModelForm):
class Meta:
model = Character
exclude = ['location', 'health', 'armour', 'owner']
Yup, thats it, create a djangoforms.ModelForm, and give it a Meta class that specifies which model object you want it to associate with, and it does. In your view you just do
form = CreateCharacterForm(request.POST)
form.save()
and it does… unless you’ve declared anything as required, and excluded it from the form at the same time. Trying to wrok out how to get access to the model object, set it’s owner value before saving it was quite hard, until I noticed a parameter on the save method, commit=True. Checking out the source, it seemed true, if you give the keyword parameter commit and set it to False, the form.save method simply sets up your model object, fills it from the form and returns it to you, unsaved. I can then do
character = form.save(commit=False)
character.owner = users.get_current_user()
character.put()
And bobs your transvestite uncle who keeps turning up to family gatherings even though nobody has invited him.
My only problem now is that having executed this once, the object should exist and be in the datastore. But my code to get it back out, doesn’t seem to work.
I’m probably doing something really stupid, but from what I can read from the docs, this code should work.
character = Character.all().filter('owner=', users.get_current_user()).fetch(1)
I’ll work on it tomorrow and see what I can get working then.
Oh last feature, and this is my favourite feature so far. While looking to try to work out if my data was in the datastore, I found the dev_appserver admin interface. It doesn’t provide you with the logs, CPU cycles used or bandwidth obviously, but it does provide the facility to dynamically examine the datastore, and an interactive python interpreter, so you can just import your model and execute query methods to your hearts content.