Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added docs on validation and polymorphism

  • Loading branch information...
commit bbd2e0142bee77e23478fbf23f0d6ddb5b9129d0 1 parent be66eeb
@zbyte64 authored
View
117 build_docs.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+import logging
+import subprocess
+import os
+
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+class LogStream(object):
+ def __init__(self, log_func):
+ self.log_func = log_func
+
+ def log_line(self, line):
+ self.log_func(line)
+
+ def writelines(self, sequence):
+ for line in sequence:
+ self.log_line(line)
+
+ def write(self, string):
+ self.log_line(string)
+
+class TaskLogger(logging.Logger):
+ def __init__(self, *args, **kwargs):
+ logging.Logger.__init__(self, *args, **kwargs)
+ self.log_stream = StringIO()
+ handler = logging.StreamHandler(self.log_stream)
+ handler.setLevel(logging.INFO)
+ formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
+ handler.setFormatter(formatter)
+ self.addHandler(handler)
+
+ def read_log(self):
+ return self.log_stream.getvalue()
+
+ def get_stdout_object(self):
+ return LogStream(self.info)
+
+ def get_stderr_object(self):
+ return LogStream(self.error)
+
+class CommandResponse(object):
+ def __init__(self, session, cmd, popen, block, logger):
+ self.session = session
+ self.cmd = cmd
+ self.popen = popen
+ self.joined = False
+ self.logger = logger
+ if block:
+ self.join()
+
+ def join(self):
+ if self.joined:
+ return
+ self.joined = True
+ self.stdout, self.stderr = self.popen.communicate()
+ if self.stdout:
+ self.logger.info(self.stdout)
+ if self.stderr:
+ self.logger.error(self.stderr)
+ self.logger.debug('Return Code: %s' % self.returncode)
+
+ @property
+ def returncode(self):
+ return self.popen.returncode
+
+class CommandFailure(Exception):
+ pass
+
+class ShellSession(object):
+ def __init__(self, logger, cwd=None, **popen_kwargs):
+ self.popen_kwargs = {
+ 'cwd': cwd or os.getcwd(),
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.PIPE,
+ }
+ self.popen_kwargs.update(popen_kwargs)
+ self.logger = logger
+
+ def run(self, cmd, block=True):
+ kwargs = dict(self.popen_kwargs)
+ if isinstance(cmd, basestring):
+ kwargs['shell'] = True
+ self.logger.info(cmd)
+ result = subprocess.Popen(cmd, **kwargs)
+ return CommandResponse(self, cmd, result, block, self.logger)
+
+ def run_with_retries(self, cmd, retries=3):
+ attempts = list()
+ while retries:
+ response = self.run(cmd)
+ if response.returncode:
+ retries -= 1
+ attempts.append(response)
+ else:
+ return response
+ raise CommandFailure('Failed to run command, # of attempts: %s' % len(attempts), attempts)
+
+ def cd(self, directory):
+ if directory.startswith('/'):
+ self.popen_kwargs['cwd'] = directory
+ else:
+ self.popen_kwargs['cwd'] = os.path.join(self.popen_kwargs['cwd'], directory)
+ self.logger.info('cd %s' % self.popen_kwargs['cwd'])
+
+if __name__ == '__main__':
+ import sys
+ logger = TaskLogger('docbuilder')
+ shell = ShellSession(logger, stdout=sys.stdout, stderr=sys.stderr)
+ shell.run('virtualenv --system-site-packages .')
+ shell.run_with_retries('bin/pip install -q -r doc_requirements.txt')
+ shell.run_with_retries('bin/pip install -q Sphinx')
+ shell.run('bin/python setup.py build_sphinx -E')
+
View
2  doc_requirements.txt
@@ -0,0 +1,2 @@
+django>=1.4
+
View
2  docs/source/index.rst
@@ -15,6 +15,8 @@ Welcome to Django DocKits's documentation!
manual/forms
manual/views
manual/indexers
+ manual/validation
+ manual/multiplerecordtypes
Download: http://github.com/webcube/django-dockit
View
62 docs/source/manual/multiplerecordtypes.rst
@@ -0,0 +1,62 @@
+=====================
+Multiple Record Types
+=====================
+
+Documents and Schemas maybe subclassed to provide polymorphic functionality. For this to work the base class must define `typed_field` in its Meta class which specifies a field name to store the type of schema. The subclasses must define `typed_key` which is to be a unique string value identifying that sublcass.
+
+Here is an example where a collection contains multiple record types::
+
+ class ParentDocument(schema.Document):
+ slug = schema.SlugField()
+
+ class Meta:
+ typed_field = '_doctype'
+
+ class Blog(ParentDocument):
+ author = schema.CharField()
+ body = schema.TextField()
+
+ class Meta:
+ typed_key = 'blog'
+
+ class Video(ParentDocument):
+ url = schema.CharField()
+ thumbnail = schema.ImageField(blank=True, null=True)
+
+ class Meta:
+ typed_key = 'video'
+
+ Blog(slug='blog-entry', author='John Smith', body='large description').save()
+ Video(slug='a-video', url='http://videos/url').save()
+
+ ParentDocument.objects.all() #an iterator containing a Blog and Video entry
+
+Embedded schemas may also take advantage of this functionality as well::
+
+ class Download(schema.Schema):
+ class Meta:
+ typed_field = '_dltype'
+
+ class Bucket(schema.Document):
+ slug = schema.SlugField()
+ downloads = schema.ListField(schema.SchemaField(Download))
+
+ class Image(Download):
+ full_image = schema.ImageField()
+
+ class Meta:
+ typed_key = 'image'
+
+ class Video(Download):
+ url = schema.CharField()
+ thumbnail = schema.ImageField(blank=True, null=True)
+
+ class Meta:
+ typed_key = 'video'
+
+ bucket = Bucket(slug='my-bucket')
+ bucket.downloads.append(Image(full_image=myfile))
+ bucket.downloads.append(Video(url='http://videos/url'))
+ bucket.save()
+
+When we retrieve our bucket later we can expect the entries in downloads to be appropriately mapped to Image and Video. Outside applications may also add other Download record types and our Bucket class will be made aware of those types.
View
5 docs/source/manual/validation.rst
@@ -0,0 +1,5 @@
+==========
+Validation
+==========
+
+Documents and Schemas support validation that mimics Django's models. Given a document instance you may call `full_clean` to validate the document structure and have a `ValidationError` raised if the document does not conform. Documents and schemas may define their own `clean_<fieldname>` method to validate each entry.
Please sign in to comment.
Something went wrong with that request. Please try again.