Showing posts with label Django. Show all posts
Showing posts with label Django. Show all posts

2014-08-19

Showing the description of a choice in a Django template

Sometimes you would like to show the description of a choice instead of its code in a Django template.  One way to achieve that is to define a property in the model and referencing it in a template as below:

    {{ object.status_desc }}

=== models.py ===

from django.db.models import IntegerField, CharField, Model

class Invoice(Model):

    STATUS_TYPE = (
        ('A', 'Active'),
        ('I', 'Inactive'),
    )

    invoice_no = IntegerField()
    status = CharField(max_length=1, choices=STATUS_TYPE, default='A')

    @property
    def status_desc(self):
        return dict(self.STATUS_TYPE)[self.status]
 
EDITED 2015-07-13 Turn out there is a django function for this purpose: Model.get_FOO_display()

2014-08-16

Django File Upload

The following is a minimalistic but complete example of handling file upload in Django 1.6.


=== forms.py ===

from django import forms

class UploadFileForm(forms.Form):
    file = forms.FileField()

=== views.py ===

import os.path
from django.http import HttpResponse
from django.shortcuts import render
from .forms import UploadFileForm
          
def home(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponse("Upload Successful.")
    else:
        form = UploadFileForm()
    return render(request, 'home.html', {'form': form})

def handle_uploaded_file(f):
    with open(os.path.join('/path/to/', f.name), 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

=== home.html ===
<html>
<body>

<form action="" method="post" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %}>
  {{ form.as_p }}
  {% csrf_token %}
  <input type="submit" value="Submit" />
</form>

</body>
</html>

2014-06-09

How is_authenticated() is done in Django?


I tried to understand how is_authenticated() is done in Django, so I did a code search in Django's GitHub repository and found two definitions of it in django/contrib/auth/models.py as shown below:


I am surprised that one definition always return true, while the other always return false, as I was expecting some sort of logic to check if a user is logged or not.

Turn out it is simpler than that. The is_authenticated() method is bound to either a User object or an AnonymousUser object. So at the time is_authenticated() is called, it already knows whether the user is authenticated or not by the type of the object.

Neat.

2013-12-08

Django 1.6 source file count and directory structure

The other day i would like to know how many source files are there in Django 1.6, so I run the following command on the django directory.  Basically
it lists all non-empty python source files and count them.

$ ls -Rl django | grep \.py$ | grep -v " 0 " | wc -l
707

I would also like to know Django 1.6 directory structure, so I run the following command on the django directory again, limiting the tree depth to two:

$tree django -d -L 2
django
|-- bin
|   `-- profiling
|-- conf
|   |-- app_template
|   |-- locale
|   |-- project_template
|   `-- urls
|-- contrib
|   |-- admin
|   |-- admindocs
|   |-- auth
|   |-- comments
|   |-- contenttypes
|   |-- flatpages
|   |-- formtools
|   |-- gis
|   |-- humanize
|   |-- messages
|   |-- redirects
|   |-- sessions
|   |-- sitemaps
|   |-- sites
|   |-- staticfiles
|   |-- syndication
|   `-- webdesign
|-- core
|   |-- cache
|   |-- checks
|   |-- files
|   |-- handlers
|   |-- mail
|   |-- management
|   |-- serializers
|   `-- servers
|-- db
|   |-- backends
|   `-- models
|-- dispatch
|-- forms
|   `-- extras
|-- http
|-- middleware
|-- shortcuts
|-- template
|   `-- loaders
|-- templatetags
|-- test
|-- utils
|   |-- 2to3_fixes
|   |-- translation
|   `-- unittest
`-- views
    |-- decorators
    `-- generic

2013-08-28

Django logging setting

It took me some time to figure out how to set up logging in Django.  What I want to do is to log to a pair of rotating files each 1MB in size.

What I come up with is the following code segment to replace the LOGGING setting in the settings.py:

U_LOGFILE_NAME = r'/path/to/log.txt'
U_LOGFILE_SIZE = 1 * 1024 * 1024
U_LOGFILE_COUNT = 2
U_LOGFILE_APP1 = 'app1'
U_LOGFILE_APP2 = 'app2'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            #'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'logfile': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': U_LOGFILE_NAME,
            'maxBytes': U_LOGFILE_SIZE,
            'backupCount': U_LOGFILE_COUNT,
            'formatter': 'standard',
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        U_LOGFILE_APP1: {
            'handlers': ['logfile'],
            'level': 'DEBUG',
            'propagate': True,
        },
        U_LOGFILE_APP2: {
            'handlers': ['logfile'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

Usage:

import os
log = logging.getLogger(__name__)

log.debug("debug")
log.info("info")
log.warn("warn")
log.error("error")

This post also appears in Django Snippets.


2013-05-14

Set up Django 1.5.1 in DreamHost VPS

This post is about setting up Django 1.5.1 in a virtualenv in DreamHost VPS with Apache2 and mod_wsgi 3.4, and is mostly an update to the following post about three years ago:
http://www.wombatnation.com/2010/06/django-on-dreamhost-ps/comment-page-1
Software Versions:

   Apache 2.2.22
   Django 1.5.1
   mod_wsgi 3.4
   PIP 1.3.1
   Python 2.6.6
   VirtualEnv 1.9.1

1. Sign up a VPS account with DreamHost.

2. Create a regular user [user] in the VPS.  The Django project will run under this account.

3. Create an admin user [admin] in the VPS to manage the web server.  This admin account has sudo privileges.

4. Install Python PIP (1.3.1)

   [admin]$ sudo easy_install pip

   PIP is installed at /usr/local/bin/pip.

5. Upgrade VirtualEnv (from 1.4.9 to 1.9.1)

   [admin]$ sudo pip install --upgrade virtualenv

6. Create a virtualenv and install Django (1.5.1) in it

   [user]$ mkdir ~/django
   [user]$ virtualenv ~/django/env
   [user]$ source  ~/django/env/bin/activate
   [env]$ pip install django

7. Create a Django project (demo)

   [env]$ cd ~/django
   [env]$ django-admin.py startproject demo

8. Verify Django project is working

   [env]$ cd ~/django/demo
   [env]$ python manage.py runserver 0.0.0.0:8000

   Visit http://your.domain.com:8000 to verify Django project is up and running.

9. Install mod_wsgi 3.4

   [admin]$ mkdir ~/src
   [admin]$ cd ~/src
   [admin]$ wget http://modwsgi.google.com/files/mod_wsgi-3.4.tar.gz
   [admin]$ tar xzvf mod_wsgi-3.4.tar.gz
   [admin]$ cd mod_wsgi-3.4
   [admin]$ ./configure --with-apxs=/usr/local/dh/apache2/template/sbin/apxs --with-python=/usr/bin/python
   [admin]$ make
   [admin]$ sudo make install

   mod_wsgi is installed at /usr/local/dh/apach2/template/lib/modules/mod_wsi.so

10. Edit httpd.conf

   [admin]$ sudo vim /usr/local/dh/apache2/apache2-psNNNNNN/etc/httpd.conf

   psNNNNNN is your VPS id.

   add the following line in the LoadModule section:
   LoadModule wsgi_module /dh/apache2/template/lib/modules/mod_wsgi.so

   add the following line outside of VirtualHost directive:
   WSGIPythonPath /home/user/django/env/lib/python2.6/site-packages

   add following line inside the VirtualHost directive:
   WSGIScriptAlias /demo /home/user/django/demo/demo/wsgi.py

11. Restart Apache

   [admin]$ sudo /etc/init.d/httpd2 restart apache2-psNNNNNN

12. Edit wsgi.py

   [env]$ vim ~/django/demo/demo/wsgi.py

   add next two lines at the top of the file:
   import sys
   sys.path.insert(0, '/home/user/django/demo')

13. Create a Django app (demoapp) and update urls.py

   [env]$ cd ~/django/demo
   [env]$ python manage.py startapp demoapp
   [env]$ vim ~/django/demo/demoapp/views.py

   Make it look like:
   from django.http import HttpResponse

   def index(request):
       return HttpResponse("Hello world!")

   [env]$ vim ~/django/demo/demo/urls.py

   Add a url pattern:
   url(r'^$', 'demoapp.views.index')

14. Verify

   Visit http://your.domain.com/demo, will see "Hello World!" in browser.

-End-