At WWU Housing, we started using the [Tempest jQuery plugin](http://plugins.jquery.com/project/tempest) for javascript templating, which has the same {{ var }} syntax as Django's templating.
We wanted to be able to use the same templates in our server-side python and our client-side js, so we had to have a way of including the unrendered template for the js. At the same time, for convenience, it had to be modular so we could push the same code from our dev- to our live-server and not worry about absolute paths (which is why the {% ssi %} tag did not work).
So the {% include_raw %} tag was born.
When you call model.changed_columns() you get a dict of all changed values.
When you call model.is_dirty() you get boolean whether or not the object has been changed since last save
Based on an answer here:http://stackoverflow.com/questions/110803/dirty-fields-in-django
but fixed and added is_dirty
This Base64Field class can be used as an alternative to a BlobField, which is not supported by Django out of the box.
The base64 encoded data can be accessed by appending _base64 to the field name. This is especially handy when using this field for sending eMails with attachment which need to be base64 encoded anyways.
**Example use:**
class Foo(models.Model):
data = Base64Field()
foo = Foo()
foo.data = 'Hello world!'
print foo.data # will 'Hello world!'
print foo.data_base64 # will print 'SGVsbG8gd29ybGQh\n'
This is based on the Admin app functionality for dispatching calls.
Once you put these two files in place then add the following to urls.py:
from myProject import ajax
urlpatterns = patterns('',
...
# Add this to the urlpatterns list
(r'^ajax/(.*)', ajax.dispatcher.urls),
...)
you register a function or method with a name like so:
from django.contrib import ajax
def myAutoCompleteCall(request):
...
ajax.dispatcher.register('myAutoComplete', myAutoCompleteCall)
Then you can use the url: `http://www.mysite.com/ajax/myAutoComplete`
Previously I had placed this app in the django\\contrib directory because I wanted to use it in an Admin app mod. Since the release of 1.1 I was able to move it out into a standard app because of the new `formfield_overrides` property of the `ModelAdmin` class.
This set of handlers allow one to isolate requests based on the method posted. Normally, in a view, we would do checks for request.method value and update the resource accordingly. This makes the view code pretty messy.
So one way to avoid these check each time is to have a handler method (resource_handler above), that checks for the method parameter and dispatches to the handler withe the prefix <method>_handler_<suffix>.
This also has the advantage of grouping related actions in a particular class. At the same time a new instance of the request handler is not created on each request (as with the google appengine handler?). Yet another advantage is by making the handler methods as class methods, the handler classes can be inherited to add further functionality to a resource "group.
The disadvantage however is the inability to restrict access to a handler method to only particular methods. Eg above the "r'obja/(?P<id>[^\/]+)/delete/" would map to the delete_handler_objects if themethod was "delete" and post_handler_objects if the method was "post". However this can be worked with a different suffix passed to the handler_params method. Infact setting the suffix to "objects_delete" would result in a "delete_handler_objects_delete" handler on delete method and a Http404 on all others.
Another inconvinience is the inability to detect a view handler by simply inspecting the url patterns. However, this information is carried within the handler_suffix and handler_class parameters which may infact provide greater insight into the semantics around the view handlers.
Needless to say, this easily extends rest based accesses.
Would greatly appreciate feedback and improvements.
After using Zope3/Grok for a little, I wondered how hard it would be to implement views as classes in Django, in a similar vain to how it's done in Grok. I came up with something rather simple but effective. It may be more appropriate if you use a template engine other than Django Templates, which allows you to call functions with arguments, but it's still useful none-the-less to encapsulate functions in a class.
You could, for example, extend View to be JinjaView, just replacing render_template().
A nice extension, I imagine, would be to automatically figure out the template name as well as the path prefix for it (since you probably want it to be found under packagename/templatename.html).
Signal to notify new saved comments.
**Example:**
from django.contrib.comment import models, signals
signals.comment_was_posted.connect(new_comment_notifier,
sender=models.Comment)
Limit rate request decorator for view.
Authenificated user can't request decorated view often then timeout.
Usage:
@limit_request_rate(time_beetween_request_sec)
def my_view(request):
...
get_cell_value from [here](http://code.activestate.com/recipes/439096/)
This is the pavement file I use to deploy a django site. It's in early stages. Right now it copies everything up to the desired server over scp. But I think I'll change it to rsync in the future.
It requires pavement, and pexpect.
The pavement file takes slight instruction from your settings.py file. For server information, and "lib_apps" to copy into the lib directory.
An example of a settings file that I use with this pavement file:
http://gitweb.codeendeavor.com/?p=django_empty.git;a=blob_plain;f=settings.py;h=23bda7d2a1eb2a52ca0859004ecccd206dade4ec;hb=5d672178dab282caeed5ff0de7ed807c72e44f74
Specifically, check out the bottom for two vars: "LIB_APPS" and "DEPLOYMENTS"
A good example of my empty django project is here:
http://gitweb.codeendeavor.com/?p=django_empty.git;a=tree;h=5d672178dab282caeed5ff0de7ed807c72e44f74;hb=5d672178dab282caeed5ff0de7ed807c72e44f74
I think the one thing that's missing is a way to re-spawn fcgi processes. Which I'll hopefully get around to adding sometime soon.
Also, I need to do a little work at making sure source control files don't get pushed through scp.