[[PageOutline(1-2,Table of contents)]] = Newbie mistakes = Please feel free to share the things that tripped you up when you started with Django. We'll try to improve Django's error handling to catch such mistakes in the future. == POST to views loses POST data == ==== Symptom ==== You've got a form that does a POST to some view, and the view doesn't get the POST data from the form. ==== Probable cause ==== You might be missing the / at the end of the form {{{action}}}. If that's the case, the {{{CommonMiddleware}}} (check your {{{MIDDLEWARE_CLASSES}}} redirects to the exact name of the view - and that always includes a trailing slash. Because it does so by using the standard HTTP redirection through Location header, it can't pass on the POST data - and that's why it gets lost. ==== Solution ==== Always make sure that your form actions end with a slash, like this: {{{
}}} Note that Django now attempts to catch this problem, as of [3109]. == Your forms do not upload files == ==== Symptom ==== You have {{{FileField()}}} and {{{ImageField()}}} fields in your form and the files are not uploaded when you submit this form ==== Probable cause ==== You might be missing the {{{request.FILES}}} argument when intantiate your {{{Form}}} object. ==== Solution ==== Always make sure that you are passing {{{request.FILES}}} when intantiate your {{{Form}}} object: {{{ form = MyForm(request.POST, request.FILES) }}} == URLconf include() misbehaving == ==== Symptom ==== You're trying to get your URLconf files to work, but getting cryptic errors about how there is no module 'index' (where 'index' is some function you are trying to assign as a view), or module 'foo' has no attribute 'urlpatterns'. ==== Probable cause ==== You may have tried to load your view files using include() in the URLconf file (in tutorial 3, this is myproject/settings/urls/main.py). The include() call assumes that the file it's loading is also a URLconf file. ==== Solution ==== Remove the include(). Just give the module and function name (e.g., {{{'myproject.apps.polls.views.polls.index'}}}) as a string, with no include() around it. == Blank object names == ==== Symptom ==== The automatic admin interface is showing nothing (or a single {{{ }}}) in the "Select [object_type] to change" view. ==== Probable cause ==== You may have forgotten to create a {{{__unicode__()}}} function for your model. Django calls {{{__unicode__()}}} to find out how to display objects in the admin interface. An alternate cause is the string you return from {{{__unicode__()}}} includes brackets (an therefore looks like an html tag), and is cleaned up by the {{{strip_tags}}} template filter, resulting in blank entries. ==== Solution ==== Add a correct {{{__unicode__()}}} function (without brackets in the output) to all your models. Make it a habit so it becomes automatic. == Integer & NULLS == ==== Problem ==== When you have a Field: {{{ #!python current_zip = meta.IntegerField(max_length=5, blank=True) }}} Django will create a not nullable field in the database. However leaving the field blank (in admin or web interface) Django will try and insert a {{{NULL}}} value in the database. ==== Solution ==== Add {{{null=True}}}: {{{ #!python current_zip = meta.IntegerField(max_length=5, null=True, blank=True) }}} == Date & NULLS == Same problem as Integer & NULLS with the same solution. == Appending to a list in session doesn't work == ==== Problem ==== If you have a list in your session, append operations don't get saved to the object. ==== Solution ==== Copy the list out of the session object, append to it, then copy it back in: {{{ sessionlist = request.session['my_list'] sessionlist.append(new_object) request.session['my_list'] = sessionlist }}} Alternatively, explicitly mark the session as modified: {{{ request.session['my_list'].append(new_object) request.session.modified = True }}} == Errors about undefined attributes with one-char names == ==== Problem ==== You get an !AttributeError with some weird attribute name that's only one char long. You don't have that attribute name anywhere in your code. ==== Solution ==== Search your model and code for situations where you have to pass a tuple of values and want to pass a tuple with one element - and that element is a string like in this sample: {{{ #!python class META: ... admin = meta.Admin( list_display = ('total_price'), ... ) }}} You are just missing a comma in the list_display assignment like this: {{{ #!python class META: ... admin = meta.Admin( list_display = ('total_price',), ... ) }}} Remember, in python: {{{ #!python >>> a = (1) ## This causes problems 1 >>> a = (1,) ## These are fine. (1,) >>> a = [1] [1] >>> a = [1,] [1] }}} Since a tuple is expected but a string provided, the code will merrily iterate over the characters of the string instead of the tuple elements - and that's where the single-char attribute names come from. If the commas are consistently causing you problems, try using brackets [] instead of parentheses. == I'm using formfields.FormWrapper and none of my form fields show up == ==== Problem ==== You are using code similar to that documented [http://www.djangoproject.com/documentation/forms/ here], but when you put {{ form.field_name }}, you get nothing. ==== Solution ==== Make sure when you create your form object, you are passing in empty '''dictionaries''', not tuples. For example: {{{ manip = things.AddManipulator() form = formfields.FormWrapper(manip, {}, {}) }}} Not: {{{ manip = things.AddManipulator() form = formfields.FormWrapper(manip, (), ()) }}} If you pass in empty tuples for data & errors, it will silently fail to insert your form fields. == Django says "Unable to Open Database File" when using SQLite3 == ==== Problem ==== You're using SQLite3, your DATABASE_NAME is set to the database file's full path, the database file is writeable by Apache, but you still get the above error. ==== Solution ==== Make sure Apache can also write to the parent directory of the database. SQLite needs to be able to write to this directory. Make sure you set perms to 0777. Just making it writable might not work Make sure each folder of your database file's full path does not start with number, eg. /www/4myweb/db (observed on Windows 2000). If DATABASE_NAME is set to something like '/Users/yourname/Sites/mydjangoproject/db/db', make sure you've created the 'db' directory first. Make sure your /tmp directory is world-writable (an unlikely cause as other thing on your system will also not work). `ls /tmp -ald` should produce `drwxrwxrwt ...`. Make sure the path to the database specified in settings.py is a full path. If you working on windows make also sure that you have the path to the db directory written with double backlashes (using os.path methods are recommended) {{{ 'C:\\django\\sqlite\\django.db' }}} or {{{ r'C:\django\sqlite\django.db' }}} Make sure there is no special charcaters in the path like "éè" or "(". If you are using Windows and this message appears intermittently make sure that your security software (Anti-malware) are not opening (and locking) your database file to check for malware presence. == How to point apache to your media files directory == ==== Problem ==== You have no clue how to map a media url to your media directory when using apache2. ==== Solution ==== Use the ''Alias'' Directive and don't forget to set-up access rights correctly. {{{ Alias /mediaurl /path/to/files Order allow,deny Allow from all }}} == QuerySets aren't Lists == ==== Problem ==== You have been playing with the database API and noticed that a returned query set looks a lot like a list: {{{ #!python >>> from mysite.polls.models import Poll,Choice >>> Poll.objects.all() [, ] ## looks a lot like a list to me }}} But, it doesn't behave like a list in some cases. ==== Solution ==== Here are a couple of cases where the behaviour is not list-like and their solution. In Python this is how we can test for an empty list: {{{ #!python >>> b=[] >>> b==[] True }}} This doesn't work with a QuerySet. You might try the following but it will fail: {{{ #!python >>> from mysite.polls.models import Poll,Choice >>> p = Poll.objects.filter(question__startswith='ZZZZZZZZZZZZ') >>> p [] >>> p==[] False }}} The way to do it is test for p.exists: {{{ #!python >>> from mysite.polls.models import Poll,Choice >>> p = Poll.objects.filter(question__startswith='ZZZZZZZZZZZZ') >>> p [] >>> p.exists() False }}} Another case occurs when you want to retrieve the last member of a QuerySet: {{{ #!python >>> from mysite.polls.models import Poll,Choice >>> p = Poll.objects.all() >>> p [, ] >>> p[-1] Traceback (most recent call last): File "", line 1, in ? File "c:\python24\lib\site-packages\django-0.95-py2.4.egg\django\db\models\query.py", line 98, in __getitem__ assert (not isinstance(k, slice) and (k >= 0)) \ AssertionError: Negative indexing is not supported. }}} The way I get the last member is: {{{ #!python >>> p[p.count()-1] }}} == Using reserved name on application breaks admin == ==== Symptom ==== After creating a new application, with a model that validates, trying to log on to the admin causes an error similar to: {{{ ImproperlyConfigured: Error importing middleware django.middleware.common: "No module named ... " }}} ==== Possible cause ==== Check to see that you didn't use a reserved name in naming your application, i.e. "email", "date" and "time" are common application names that would validate when the server starts but will break Django's admin. ==== Solution ==== Rename your application directory using a non-reserved name, i.e., "email_app" instead of "email". Go into the {{{INSTALLED_APPS}}} section of settings.py and change the name there too. Also, don't forget to do a syncdb to create the newly renamed app in your database. You may also want to go in to your database and drop the old "mis-named" table. == unbound method contribute_to_class() == ==== Symptom ==== A model does not validate with the following message: {{{ Validating models... project.allication: Error when calling the metaclass bases unbound method contribute_to_class() must be called with TextField instance as first argument (got ModelBase instance instead) 1 error found. }}} ==== Possible Cause ==== A model field was not declared properly, the parentheses after the field types name were missing: wrong: {{{ #!python class Content(models.Model): content = models.TextField }}} correct: {{{ #!python class Content(models.Model): content = models.TextField() }}} ==== Solution ==== A model field is an ''instance'' of the appropriate `Field` class, so the parentheses are required. == Permission denied when using static serve == ==== Possible cause ==== The ADMIN_MEDIA_PREFIX is the same as MEDIA_URL in settings.py ==== Solution ==== Ensure they have different values - e.g. ADMIN_MEDIA_PREFIX = 'admin-media' and MEDIA_URL = '/media' == Default value and Callables == ==== Symptom ==== You call a method to set a default value, such as random.randint(), but the value is the same for every new instance of your object. ==== Probable cause ==== Each new instance doesn't call random.randint() ==== Solution ==== Prepend "lambda:" like {{{ #!python MyRandNum = models.CharField(max_length=4, default=lambda:random.randint(1000,9999)) }}} == PageNotFound == Using the URLconf defined in wikicamp.urls, Django tried these URL patterns, in this order: {{{ ^wikicamp/(?P[^/+])/edit/$ ^wikicamp/(?P[^/+])/save/$ ^wikicamp/(?P[^/+])/$ }}} The current URL, , didn't match any of these. ==== Solution ==== == BLANK form == Be it a normal form , model form or class-based-view The page display a blank (empty) page ==== Problem ==== One possible reason might be you forgot to add {% block content %} {% endblock %} in your template file ==== Solution ==== Make sure that template used to display the page actually contains the tags {% block content %} {% endblock %} wrapping your form definition in the template file.