Ajout exemple
authorCyril Robert <Cyril Robert crobert@inverse.ca>
Fri, 5 Feb 2010 20:02:58 +0000 (15:02 -0500)
committerCyril Robert <Cyril Robert crobert@inverse.ca>
Fri, 5 Feb 2010 20:02:58 +0000 (15:02 -0500)
14 files changed:
__init__.py [new file with mode: 0644]
django_exportateur/exportateur.py [new file with mode: 0644]
django_exportateur/models.py
django_exportateur/views.py [deleted file]
exemple/__init__.py [new file with mode: 0644]
exemple/manage.py [new file with mode: 0644]
exemple/settings.py [new file with mode: 0644]
exemple/urls.py [new file with mode: 0644]
exemple/voiture/__init__.py [new file with mode: 0644]
exemple/voiture/admin.py [new file with mode: 0644]
exemple/voiture/models.py [new file with mode: 0644]
exemple/voiture/templates/index.html [new file with mode: 0644]
exemple/voiture/tests.py [new file with mode: 0644]
exemple/voiture/views.py [new file with mode: 0644]

diff --git a/__init__.py b/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/django_exportateur/exportateur.py b/django_exportateur/exportateur.py
new file mode 100644 (file)
index 0000000..a905c15
--- /dev/null
@@ -0,0 +1,73 @@
+from django.http import HttpResponse
+import csv
+from StringIO import StringIO
+from odf.opendocument import OpenDocumentSpreadsheet
+from odf.style import Style, TextProperties, TableColumnProperties
+from odf.text import P
+from odf.table import Table, TableRow, TableCell
+
+mimetypes = {"csv": "text/csv", \
+        "ods": "application/vnd.oasis.opendocument.spreadsheet"}
+
+def export_csv (headers, data):
+    buffer = StringIO ()
+    writer = csv.writer (buffer)
+    if len (headers) > 0:
+        writer.writerow (headers)
+    for line in data:
+        writer.writerow (line)
+
+    return buffer.getvalue ()
+
+def export_ods (headers, data):
+    doc = OpenDocumentSpreadsheet()
+    style = Style(name="Large number", family="table-cell")
+    style.addElement(TextProperties(fontfamily="Arial", fontsize="15pt"))
+    doc.styles.addElement(style)
+    widewidth = Style(name="co1", family="table-column")
+    widewidth.addElement(TableColumnProperties(columnwidth="2.8cm", breakbefore="auto"))
+    doc.automaticstyles.addElement(widewidth)
+
+    table = Table()
+    if len (headers) > 0:
+        tr = TableRow ()
+        table.addElement (tr)
+        for item in headers:
+            tc = TableCell ()
+            tr.addElement (tc)
+            p = P(stylename = style, text = unicode (item, "utf-8"))
+            tc.addElement (p)
+
+    for line in data:
+        tr = TableRow ()
+        table.addElement (tr)
+        for item in line:
+            tc = TableCell ()
+            tr.addElement (tc)
+            p = P (stylename = style, text = unicode (item, "utf-8"))
+            tc.addElement (p)
+
+    doc.spreadsheet.addElement(table)
+    buffer = StringIO ()
+    doc.write(buffer)
+
+    return buffer.getvalue ()
+
+
+def exportateur (headers = [], data = [], type = "csv", filename = None):
+    content = None
+    if type == "csv":
+        content = export_csv (headers, data)
+    elif type == "ods":
+        content = export_ods (headers, data)
+    else:
+        raise "Type d'exportateur inconnu: %s" % type
+
+    if filename is None:
+        filename = "exportateur.%s" % type
+
+    response = HttpResponse (mimetype = mimetypes[type])
+    response['Content-Disposition'] = "attachment; filename=\"%s\"" % filename
+    response.write (content)
+
+    return response
index cb33228..72253df 100644 (file)
@@ -1,66 +1,4 @@
-import csv
 from django.db import models
-from StringIO import StringIO
-from odf.opendocument import OpenDocumentSpreadsheet
-from odf.style import Style, TextProperties, TableColumnProperties
-from odf.text import P
-from odf.table import Table, TableRow, TableCell
-
-
-
-def export_csv (headers, data):
-    buffer = StringIO ()
-    writer = csv.writer (buffer)
-    if len (headers) > 0:
-        writer.writerow (headers)
-    for line in data:
-        writer.writerow (line)
-
-    return buffer.getvalue ()
-
-def export_ods (headers, data):
-    doc = OpenDocumentSpreadsheet()
-    style = Style(name="Large number", family="table-cell")
-    style.addElement(TextProperties(fontfamily="Arial", fontsize="15pt"))
-    doc.styles.addElement(style)
-    widewidth = Style(name="co1", family="table-column")
-    widewidth.addElement(TableColumnProperties(columnwidth="2.8cm", breakbefore="auto"))
-    doc.automaticstyles.addElement(widewidth)
-
-    table = Table()
-    if len (headers) > 0:
-        tr = TableRow ()
-        table.addElement (tr)
-        for item in headers:
-            tc = TableCell ()
-            tr.addElement (tc)
-            p = P(stylename = style, text = unicode (item, "utf-8"))
-            tc.addElement (p)
-
-    for line in data:
-        tr = TableRow ()
-        table.addElement (tr)
-        for item in line:
-            tc = TableCell ()
-            tr.addElement (tc)
-            p = P (stylename = style, text = unicode (item, "utf-8"))
-            tc.addElement (p)
-
-    doc.spreadsheet.addElement(table)
-    buffer = StringIO ()
-    doc.write(buffer)
-
-    return buffer.getvalue ()
-
-
-def exportateur (headers = [], data = [], type = "csv"):
-    if type == "csv":
-        return export_csv (headers, data)
-    elif type == "ods":
-        return export_ods (headers, data)
-    else:
-        raise "Type d'exportateur inconnu: %s" % type
-
 
 def object_fields (instance, ignore = []):
     fields = []
@@ -76,20 +14,28 @@ def object_fields (instance, ignore = []):
 
     return (fields, headers)
 
-def object_values (instance, fields):
-    values = []
+def object_values (instance, fields, choice_values = True):
+    sorted_values = []
+    values = {}
 
-    for field in fields:
-        val = getattr (instance, field)
-        if val is None:
-            val = u""
-        if hasattr (val, "encode"):
-            val = val.encode("utf-8")
+    for field in instance._meta.fields:
+        if choice_values:
+            value = instance._get_FIELD_display (field)
         else:
-            val = str(val)
-        values.append(val)
+            value = getattr (instance, field.name)
+        if value is None:
+            value = u""
+        if hasattr (value, "encode"):
+            value = value.encode("utf-8")
+        else:
+            value = str(value)
+        values[field.name] = value
+
+
+    for field in fields:
+        sorted_values.append (values[field])
 
-    return values
+    return sorted_values
 
 setattr (models.Model, 'object_fields', object_fields)
 setattr (models.Model, 'object_values', object_values)
diff --git a/django_exportateur/views.py b/django_exportateur/views.py
deleted file mode 100644 (file)
index 60f00ef..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# Create your views here.
diff --git a/exemple/__init__.py b/exemple/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/exemple/manage.py b/exemple/manage.py
new file mode 100644 (file)
index 0000000..5e78ea9
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
diff --git a/exemple/settings.py b/exemple/settings.py
new file mode 100644 (file)
index 0000000..b217682
--- /dev/null
@@ -0,0 +1,83 @@
+# Django settings for exemple project.
+import os
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = 'exemple.db'             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'cd$@yd0shvruvt545&=pm(dbd4a$psh78z(^(uu@0hh%b$l5nr'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'exemple.urls'
+
+TEMPLATE_DIRS = (
+    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+    # Always use forward slashes, even on Windows.
+    # Don't forget to use absolute paths, not relative paths.
+    os.path.join(os.path.dirname(__file__), 'voiture', 'templates').replace('\\', '/')
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.admin',
+    'voiture',
+)
diff --git a/exemple/urls.py b/exemple/urls.py
new file mode 100644 (file)
index 0000000..157c5c0
--- /dev/null
@@ -0,0 +1,19 @@
+from django.conf.urls.defaults import *
+
+# Uncomment the next two lines to enable the admin:
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^exemple/', include('exemple.foo.urls')),
+
+    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
+    # to INSTALLED_APPS to enable admin documentation:
+    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    # Uncomment the next line to enable the admin:
+    (r'^admin/', include(admin.site.urls)),
+    (r'^$', 'voiture.views.index'),
+    (r'^export/(\w+)$', 'voiture.views.export'),
+)
diff --git a/exemple/voiture/__init__.py b/exemple/voiture/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/exemple/voiture/admin.py b/exemple/voiture/admin.py
new file mode 100644 (file)
index 0000000..a9cc492
--- /dev/null
@@ -0,0 +1,5 @@
+from models import Marque, Voiture
+from django.contrib import admin
+
+admin.site.register (Marque)
+admin.site.register (Voiture)
diff --git a/exemple/voiture/models.py b/exemple/voiture/models.py
new file mode 100644 (file)
index 0000000..a207c81
--- /dev/null
@@ -0,0 +1,20 @@
+# coding=utf-8
+from django.db import models
+from django_exportateur import *
+
+class Marque (models.Model):
+    id = models.AutoField (primary_key = True)
+    nom = models.CharField (max_length = 32, verbose_name = "Marque")
+
+    def __unicode__ (self):
+        return "<Marque %s>" % self.nom
+
+class Voiture (models.Model):
+    id = models.AutoField (primary_key = True, verbose_name = "Numero")
+    marque = models.ForeignKey (Marque)
+    couleur = models.CharField (max_length = 32, verbose_name = "Couleur")
+    condition = models.CharField (max_length = 1, choices = \
+            (('N', 'Neuve'), ('U', 'Usagée'), ('A', 'Accidentée')))
+
+    def __unicode__ (self):
+        return "<Voiture %s>" % self.id
diff --git a/exemple/voiture/templates/index.html b/exemple/voiture/templates/index.html
new file mode 100644 (file)
index 0000000..63f560d
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+    <head>
+        <title>django-exportateur</title>
+    </head>
+    <body>
+        <h1>django-exportateur</h1>
+        <h2>Utilisation</h2>
+        <ol>
+            <li>Aller dans l'<a href="/admin/">admin</a> pour creer des objets</li>
+            <li>Cliquer sur un des liens:
+            <ul>
+                <li><a href="{% url voiture.views.export "ods" %}">ODS</a></li>
+                <li><a href="{% url voiture.views.export "csv" %}">CSV</a></li>
+            </ul>
+            </li>
+        </ol>
+    </body>
+</html>
diff --git a/exemple/voiture/tests.py b/exemple/voiture/tests.py
new file mode 100644 (file)
index 0000000..2247054
--- /dev/null
@@ -0,0 +1,23 @@
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/exemple/voiture/views.py b/exemple/voiture/views.py
new file mode 100644 (file)
index 0000000..360b244
--- /dev/null
@@ -0,0 +1,32 @@
+# coding=utf-8
+from django.shortcuts import render_to_response
+from voiture.models import Voiture
+from django.template import Context
+from django_exportateur import exportateur
+
+def index (request):
+    return render_to_response ("index.html", \
+            Context ())
+
+def export (request, type):
+    list = Voiture.objects.all ()
+    tmp = list[0]
+
+    # Cherche les fields (noms des attributs), et les headers (verbose_names)
+    (v_fields, v_headers)  = tmp.object_fields (ignore = ("marque",))
+    # On veut aussi afficher les attributes de la marque
+    (m_fields, m_headers) = tmp.marque.object_fields (ignore = ("id",))
+
+    # Dans les resultats, les donnes de la marque seront affichées 
+    # dans les dernieres colonnes.
+    v_headers.extend (m_headers)
+
+    # On va chercher toutes les données
+    data = []
+    for v in list:
+        row = v.object_values (v_fields)
+        row.extend (v.marque.object_values (m_fields))
+        data.append (row)
+
+    # exportateur retourne un HttpResponse
+    return exportateur.exportateur (v_headers, data, type)