Permalink
Browse files

Initial Commit

  • Loading branch information...
0 parents commit 4c2ac589cecc5a4f57a1faaa6962d96839044ad1 @rhblind committed Sep 28, 2012
Showing with 214 additions and 0 deletions.
  1. +17 −0 .gitignore
  2. +13 −0 LICENSE.md
  3. +1 −0 README.md
  4. +163 −0 gcharts/__init__.py
  5. +3 −0 gcharts/models.py
  6. +16 −0 gcharts/tests.py
  7. +1 −0 gcharts/views.py
  8. 0 requirements.txt
@@ -0,0 +1,17 @@
+*.a
+*.class
+*.dll
+*.dylib
+*.exe
+*.o
+*.obj
+*.pyc
+*.pyo
+*.so
+*.log
+.svn
+_svn
+.DS_Store
+.project
+.pydevproject
+.settings
@@ -0,0 +1,13 @@
+Copyright © 2012 Rolf Håvard Blindheim
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
@@ -0,0 +1 @@
+Yet another Google Charts library for Django
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*-
+
+from django.db import models
+from django.db.models.query import QuerySet, ValuesQuerySet
+
+try:
+ import gviz_api
+except ImportError:
+ raise ImportError("You must install the gviz_api library.")
+
+class GChartsManager(models.Manager):
+
+ def get_query_set(self):
+ return GChartsQuerySet(self.model, using=self._db)
+
+ def to_string(self, *args, **kwargs):
+ return self.get_query_set().to_string(*args, **kwargs)
+
+ def to_javascript(self, name, *args, **kwargs):
+ return self.get_query_set().to_javascript(name, *args, **kwargs)
+
+ def to_html(self, *args, **kwargs):
+ return self.get_query_set().to_html(*args, **kwargs)
+
+ def to_csv(self, *args, **kwargs):
+ return self.get_query_set().to_csv(*args, **kwargs)
+
+ def to_tsv_excel(self, *args, **kwargs):
+ return self.get_query_set().to_tsv_excel(*args, **kwargs)
+
+ def to_json(self, **kwargs):
+ return self.get_query_set().to_json(**kwargs)
+
+ def to_json_response(self, *args, **kwargs):
+ return self.get_query_set().to_json_response(*args, **kwargs)
+
+ def to_response(self, *args, **kwargs):
+ return self.get_query_set().to_response(*args, **kwargs)
+
+
+class GChartsQuerySet(QuerySet):
+ """
+ A QuerySet which returns google charts compatible data
+ output
+ """
+ def __init__(self, *args, **kwargs):
+ super(GChartsQuerySet, self).__init__(*args, **kwargs)
+
+ def __javascript_field__(self, field):
+ """
+ Return the javascript data type for
+ field
+ """
+ fields = {
+ ("CharField", "CommaSeparatedIntegerField", "EmailField",
+ "FilePathField", "IPAddressField", "GenericIPAddressField",
+ "SlugField", "TextField", "URLField"): "string",
+ ("AutoField", "DecimalField", "FloatField", "IntegerField",
+ "BigIntegerField", "PositiveIntegerField", "ForeignKey",
+ "PositiveSmallIntegerField", "SmallIntegerField"): "number",
+ ("BooleanField", "NullBooleanField"): "boolean",
+ ("DateField"): "date",
+ ("DateTimeField"): "datetime",
+ ("TimeField"): "timeofday",
+ }
+
+ for k, v in fields.iteritems():
+ if field.get_internal_type() in k:
+ return v
+ # Should never hit this
+ raise KeyError("%s is not a valid field" % field)
+
+ def table_description(self, **kwargs):
+ """
+ Create table description for QuerySet
+ """
+ # TODO: Implement support for extra fields
+ table = {}
+ labels = kwargs.pop("labels", {})
+ fields = getattr(self, "field_names", self.model._meta.get_all_field_names())
+ defaults = dict([(k, k) for k in fields])
+ for f in self.model._meta.fields:
+ if f.attname in labels:
+ labels[f.name] = labels.pop(f.attname)
+ defaults.update(**labels)
+ if f.name in defaults:
+ f_jstype = self.__javascript_field__(f)
+ table.update({f.name: (f_jstype, defaults[f.name])})
+ return table
+
+ def values(self, *fields):
+ return self._clone(klass=GChartsValuesQuerySet, setup=True, _fields=fields)
+
+ def values_list(self, *fields, **kwargs):
+ flat = kwargs.pop('flat', False)
+ if kwargs:
+ raise TypeError('Unexpected keyword arguments to values_list: %s'
+ % (kwargs.keys(),))
+ if flat and len(fields) > 1:
+ raise TypeError("'flat' is not valid when values_list is called with more than one field.")
+ return self._clone(klass=GChartsValuesListQuerySet, setup=True, flat=flat,
+ _fields=fields)
+
+ #
+ # Methods which serialize data to various outputs
+ # These methods does _not_ return a new QuerySet
+ #
+
+ def to_json(self, **kwargs):
+ """
+ Return QuerySet data as json serialized string.
+
+ kwargs:
+ columns_order: iterable with field names in which the
+ columns should be ordered.
+ labels: dictionary mapping {'field': 'label'}
+ where field is the name of the field in model,
+ and label is the desired label on the chart.
+ """
+
+ labels = kwargs.pop("labels", {})
+ columns_order = kwargs.pop("columns_order", None)
+
+ assert isinstance(labels, dict), \
+ "labels must be a dictionary {'field_name': 'label'}"
+
+ table_description = self.table_description(labels=labels)
+ fields = table_description.keys()
+ data_table = gviz_api.DataTable(table_description=table_description,
+ data=self.values(*fields))
+ return data_table.ToJSon(columns_order=columns_order)
+
+ #
+ # Methods that modifies database are not allowed
+ #
+ def create(self, *kwargs):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+ def bulk_create(self, objs):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+ def get_or_create(self, *kwargs):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+ def delete(self):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+ def update(self, *kwargs):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+ def _update(self, *kwargs):
+ raise NotImplementedError("GChartsQuerySet is not able to modify the database")
+
+
+class GChartsValuesQuerySet(GChartsQuerySet, ValuesQuerySet):
+ def __init__(self, *args, **kwargs):
+ super(GChartsValuesQuerySet, self).__init__(*args, **kwargs)
+
+
+class GChartsValuesListQuerySet(GChartsValuesQuerySet):
+ def __init__(self, *args, **kwargs):
+ super(GChartsValuesListQuerySet, self).__init__(*args, **kwargs)
+
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this 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.assertEqual(1 + 1, 2)
@@ -0,0 +1 @@
+# Create your views here.
No changes.

0 comments on commit 4c2ac58

Please sign in to comment.