Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

first example project added (blog example); some tiny changes in mong…

…oforms (styling, added asserts). added .gitignore.
  • Loading branch information...
commit 1e58f6354a50b0fc9bbf06dfe8423cb8a94b33e3 1 parent bc65868
Florian Schlachter flosch authored committed
4 .gitignore
... ... @@ -0,0 +1,4 @@
  1 +secret.txt
  2 +*.db
  3 +*.pyc
  4 +.DS_Store
0  examples/blogprj/__init__.py
No changes.
0  examples/blogprj/apps/__init__.py
No changes.
0  examples/blogprj/apps/blog/__init__.py
No changes.
9 examples/blogprj/apps/blog/forms.py
... ... @@ -0,0 +1,9 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +from mongoforms import MongoForm
  4 +from models import BlogPost
  5 +
  6 +class BlogPostForm(MongoForm):
  7 + class Meta:
  8 + document = BlogPost
  9 + fields = ('author', 'title', 'content', 'published')
43 examples/blogprj/apps/blog/models.py
... ... @@ -0,0 +1,43 @@
  1 +import datetime
  2 +
  3 +from django.template.defaultfilters import slugify
  4 +from django.core.urlresolvers import reverse
  5 +
  6 +from mongoengine import *
  7 +
  8 +class BlogPost(Document):
  9 + published = BooleanField(default=False)
  10 + author = StringField(required=True)
  11 + title = StringField(required=True)
  12 + slug = StringField()
  13 + content = StringField(required=True)
  14 +
  15 + datetime_added = DateTimeField(default=datetime.datetime.now)
  16 +
  17 + def save(self):
  18 + if self.slug is None:
  19 + slug = slugify(self.title)
  20 + new_slug = slug
  21 + c = 1
  22 + while True:
  23 + try:
  24 + BlogPost.objects.get(slug=new_slug)
  25 + except BlogPost.DoesNotExist:
  26 + break
  27 + else:
  28 + c += 1
  29 + new_slug = '%s-%s' % (slug, c)
  30 + self.slug = new_slug
  31 + return super(BlogPost, self).save()
  32 +
  33 + def get_absolute_url(self):
  34 + #return u'%s/' % self.slug
  35 + return reverse('apps.blog.views.show', kwargs={'slug': self.slug})
  36 +
  37 + @queryset_manager
  38 + def published_posts(doc_cls, queryset):
  39 + return queryset(published=True)
  40 +
  41 + meta = {
  42 + 'ordering': ['-datetime_added']
  43 + }
1  examples/blogprj/apps/blog/templates/blog/base.html
... ... @@ -0,0 +1 @@
  1 +{% extends "base.html" %}
9 examples/blogprj/apps/blog/templates/blog/index.html
... ... @@ -0,0 +1,9 @@
  1 +{% extends "blog/base.html" %}
  2 +
  3 +{% block body %}
  4 + <a href="/new/">New post</a>
  5 +
  6 + {% for post in posts %}
  7 + {% include "blog/post.html" %}
  8 + {% endfor %}
  9 +{% endblock %}
20 examples/blogprj/apps/blog/templates/blog/new_or_edit.html
... ... @@ -0,0 +1,20 @@
  1 +{% extends "blog/base.html" %}
  2 +
  3 +{% block header %}
  4 + <style type="text/css" media="screen">
  5 + form label {
  6 + display: block;
  7 + font-weight: bold;
  8 + }
  9 + </style>
  10 +{% endblock %}
  11 +
  12 +{% block body %}
  13 + <a href="/">Back to index</a>
  14 +
  15 + <form method="post" action=".">
  16 + {{ form.as_p }}
  17 +
  18 + <input type="submit" value="Submit" id="" />
  19 + </form>
  20 +{% endblock %}
17 examples/blogprj/apps/blog/templates/blog/post.html
... ... @@ -0,0 +1,17 @@
  1 +<div class="post
  2 + {% if not post.published %}
  3 + not_published
  4 + {% endif %}">
  5 + <h1 class="title">
  6 + <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
  7 + <span style="font-size: 50%">
  8 + {% if not post.published %}
  9 + <em>(unpublished)</em>
  10 + {% endif %}
  11 + <a href="{{ post.get_absolute_url }}edit/">edit</a>
  12 + <a href="{{ post.get_absolute_url }}delete/">delete</a>
  13 + </h1>
  14 + <span class="author">by {{ post.author }}</span>
  15 + <p class="content">{{ post.content }}</p>
  16 + <span class="added">{{ post.datetime_added }}</span>
  17 +</div>
8 examples/blogprj/apps/blog/templates/blog/show.html
... ... @@ -0,0 +1,8 @@
  1 +{% extends "base.html" %}
  2 +
  3 +{% block body %}
  4 + <a href="/">Back to index</a>
  5 +
  6 + {% include "blog/post.html" %}
  7 +{% endblock %}
  8 +
16 examples/blogprj/apps/blog/urls.py
... ... @@ -0,0 +1,16 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +from django.conf.urls.defaults import *
  4 +from django.views.generic.simple import redirect_to, direct_to_template
  5 +
  6 +entry_pattern = patterns('apps.blog.views',
  7 + (r'^$', 'show'),
  8 + (r'^edit/$', 'edit'),
  9 + (r'^delete/$', 'delete'),
  10 +)
  11 +
  12 +urlpatterns = patterns('apps.blog.views',
  13 + (r'^$', 'index'),
  14 + (r'^new/$', 'new'),
  15 + (r'^(?P<slug>[\w\-]+)/', include(entry_pattern)),
  16 +)
69 examples/blogprj/apps/blog/views.py
... ... @@ -0,0 +1,69 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +from django.shortcuts import render_to_response
  4 +from django.template import RequestContext
  5 +from django.http import HttpResponseRedirect
  6 +
  7 +from models import BlogPost
  8 +from forms import BlogPostForm
  9 +
  10 +def index(request, slug=None, template_name='blog/index.html'):
  11 + posts = BlogPost.objects[:5]
  12 + template_context = {'posts': posts}
  13 + #print posts[0].get_absolute_url()
  14 + return render_to_response(
  15 + template_name,
  16 + template_context,
  17 + RequestContext(request)
  18 + )
  19 +
  20 +def show(request, slug, template_name='blog/show.html'):
  21 + post = BlogPost.objects.get(slug=slug)
  22 + template_context = {'post': post}
  23 +
  24 + return render_to_response(
  25 + template_name,
  26 + template_context,
  27 + RequestContext(request)
  28 + )
  29 +
  30 +def new(request, template_name='blog/new_or_edit.html'):
  31 + if request.method == 'POST':
  32 + form = BlogPostForm(request.POST)
  33 + if form.is_valid():
  34 + form.save()
  35 + return HttpResponseRedirect("/")
  36 + else:
  37 + form = BlogPostForm()
  38 +
  39 + template_context = {'form': form}
  40 +
  41 + return render_to_response(
  42 + template_name,
  43 + template_context,
  44 + RequestContext(request)
  45 + )
  46 +
  47 +def delete(request, slug):
  48 + post = BlogPost.objects(slug=slug)
  49 + post.delete()
  50 + return HttpResponseRedirect("/")
  51 +
  52 +def edit(request, slug, template_name='blog/new_or_edit.html'):
  53 +
  54 + post = BlogPost.objects.get(slug=slug)
  55 + if request.method == 'POST':
  56 + form = BlogPostForm(request.POST, instance=post)
  57 + if form.is_valid():
  58 + form.save()
  59 + return HttpResponseRedirect(post.get_absolute_url())
  60 + else:
  61 + form = BlogPostForm(instance=post)
  62 +
  63 + template_context = {'form': form}
  64 +
  65 + return render_to_response(
  66 + template_name,
  67 + template_context,
  68 + RequestContext(request)
  69 + )
11 examples/blogprj/manage.py
... ... @@ -0,0 +1,11 @@
  1 +#!/usr/bin/env python
  2 +from django.core.management import execute_manager
  3 +try:
  4 + import settings # Assumed to be in the same directory.
  5 +except ImportError:
  6 + import sys
  7 + 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__)
  8 + sys.exit(1)
  9 +
  10 +if __name__ == "__main__":
  11 + execute_manager(settings)
63 examples/blogprj/settings.py
... ... @@ -0,0 +1,63 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +import platform
  4 +import sys
  5 +import os
  6 +
  7 +PROJECT_ROOT = os.path.dirname(__file__)
  8 +sys.path.append(os.path.join(PROJECT_ROOT, '../../../'))
  9 +from mongoengine import connect
  10 +
  11 +connect('mongoforms_test')
  12 +
  13 +DEBUG = True
  14 +TEMPLATE_DEBUG = DEBUG
  15 +
  16 +sys.path.append(os.path.join(PROJECT_ROOT, '../../'))
  17 +
  18 +MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'site_media')
  19 +TEMPLATE_DIRS = [os.path.join(PROJECT_ROOT, 'templates')]
  20 +ADMIN_MEDIA_PREFIX = '/media/'
  21 +ROOT_URLCONF = 'blogprj.urls'
  22 +TIME_ZONE = 'Europe/Berlin'
  23 +LANGUAGE_CODE = 'de-de'
  24 +
  25 +TEMPLATE_LOADERS = (
  26 + 'django.template.loaders.filesystem.Loader',
  27 + 'django.template.loaders.app_directories.Loader',
  28 +)
  29 +
  30 +INSTALLED_APPS = (
  31 + 'apps.blog',
  32 +)
  33 +
  34 +MIDDLEWARE_CLASSES = (
  35 + 'django.middleware.common.CommonMiddleware',
  36 + 'django.contrib.sessions.middleware.SessionMiddleware',
  37 + 'django.contrib.auth.middleware.AuthenticationMiddleware',
  38 + 'django.contrib.messages.middleware.MessageMiddleware',
  39 +)
  40 +
  41 +TEMPLATE_CONTEXT_PROCESSORS = (
  42 + "django.core.context_processors.request",
  43 + "django.core.context_processors.auth",
  44 + "django.core.context_processors.media",
  45 + "django.core.context_processors.debug",
  46 +)
  47 +
  48 +try:
  49 + SECRET_KEY
  50 +except NameError:
  51 + SECRET_FILE = os.path.join(PROJECT_ROOT, 'secret.txt')
  52 + try:
  53 + SECRET_KEY = open(SECRET_FILE).read().strip()
  54 + except IOError:
  55 + try:
  56 + from random import choice
  57 + SECRET_KEY = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])
  58 + secret = file(SECRET_FILE, 'w')
  59 + secret.write(SECRET_KEY)
  60 + secret.close()
  61 + except IOError:
  62 + Exception('Please create a %s file with random characters to generate your secret key!' % SECRET_FILE)
  63 +
17 examples/blogprj/templates/base.html
... ... @@ -0,0 +1,17 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3 +<html>
  4 +<head>
  5 + <title>My little blog</title>
  6 +
  7 + {% block header %}{% endblock %}
  8 + <style type="text/css" media="screen">
  9 + .not_published {
  10 + color: #B4B4B4 !important;
  11 + }
  12 + </style>
  13 +</head>
  14 +<body>
  15 + {% block body %}Content goes here{% endblock %}
  16 +</body>
  17 +</html>
5 examples/blogprj/urls.py
... ... @@ -0,0 +1,5 @@
  1 +from django.conf.urls.defaults import *
  2 +
  3 +urlpatterns = patterns('',
  4 + (r'^', include('apps.blog.urls')),
  5 +)
9 mongoforms/fields.py
@@ -4,15 +4,16 @@ class MongoFormFieldGenerator(object):
4 4 """This class generates Django form-fields for mongoengine-fields."""
5 5
6 6 def generate(self, field_name, field):
7   - """
8   - Tries to lookup a matching formfield generator (lowercase
  7 + """Tries to lookup a matching formfield generator (lowercase
9 8 field-classname) and raises a NotImplementedError of no generator
10 9 can be found.
11 10 """
12 11 if hasattr(self, 'generate_%s' % field.__class__.__name__.lower()):
13   - return getattr(self, 'generate_%s' % field.__class__.__name__.lower())(field_name, field)
  12 + return getattr(self, 'generate_%s' % \
  13 + field.__class__.__name__.lower())(field_name, field)
14 14 else:
15   - raise NotImplementedError('%s is not supported by MongoForm' % field.__class__.__name__)
  15 + raise NotImplementedError('%s is not supported by MongoForm' % \
  16 + field.__class__.__name__)
16 17
17 18 def generate_stringfield(self, field_name, field):
18 19 if field.regex:
26 mongoforms/forms.py
... ... @@ -1,15 +1,19 @@
  1 +import types
1 2 from django import forms
2 3 from django.utils.datastructures import SortedDict
3 4 from mongoengine.base import BaseDocument
4 5 from fields import MongoFormFieldGenerator
5 6 from utils import mongoengine_validate_wrapper, iter_valid_fields
6 7
  8 +__all__ = ('MongoForm',)
  9 +
7 10 class MongoFormMetaClass(type):
8 11 """Metaclass to create a new MongoForm."""
9 12
10 13 def __new__(cls, name, bases, attrs):
11 14 # get all valid existing Fields and sort them
12   - fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, forms.Field)]
  15 + fields = [(field_name, attrs.pop(field_name)) for field_name, obj in \
  16 + attrs.items() if isinstance(obj, forms.Field)]
13 17 fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
14 18
15 19 # get all Fields from base classes
@@ -21,16 +25,19 @@ def __new__(cls, name, bases, attrs):
21 25 attrs['base_fields'] = SortedDict(fields)
22 26
23 27 # Meta class available?
24   - if 'Meta' in attrs and hasattr(attrs['Meta'], 'document') and issubclass(attrs['Meta'].document, BaseDocument):
  28 + if 'Meta' in attrs and hasattr(attrs['Meta'], 'document') and \
  29 + issubclass(attrs['Meta'].document, BaseDocument):
25 30 doc_fields = SortedDict()
26 31
27   - formfield_generator = getattr(attrs['Meta'], 'formfield_generator', MongoFormFieldGenerator)()
  32 + formfield_generator = getattr(attrs['Meta'], 'formfield_generator', \
  33 + MongoFormFieldGenerator)()
28 34
29 35 # walk through the document fields
30 36 for field_name, field in iter_valid_fields(attrs['Meta']):
31 37 # add field and override clean method to respect mongoengine-validator
32 38 doc_fields[field_name] = formfield_generator.generate(field_name, field)
33   - doc_fields[field_name].clean = mongoengine_validate_wrapper(doc_fields[field_name].clean, field._validate)
  39 + doc_fields[field_name].clean = mongoengine_validate_wrapper(
  40 + doc_fields[field_name].clean, field._validate)
34 41
35 42 # write the new document fields to base_fields
36 43 doc_fields.update(attrs['base_fields'])
@@ -45,9 +52,15 @@ class MongoForm(forms.BaseForm):
45 52 """Base MongoForm class. Used to create new MongoForms"""
46 53 __metaclass__ = MongoFormMetaClass
47 54
48   - def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None, error_class=forms.util.ErrorList, label_suffix=':', empty_permitted=False, instance=None):
  55 + def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None,
  56 + error_class=forms.util.ErrorList, label_suffix=':',
  57 + empty_permitted=False, instance=None):
49 58 """ initialize the form"""
50 59
  60 + assert isinstance(instance, (types.NoneType, BaseDocument)), \
  61 + 'instance must be a mongoengine document, not %s' % \
  62 + type(instance).__name__
  63 +
51 64 assert hasattr(self, 'Meta'), 'Meta class is needed to use MongoForm'
52 65 # new instance or updating an existing one?
53 66 if instance is None:
@@ -71,7 +84,8 @@ def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None, error_
71 84 object_data.update(initial)
72 85
73 86 self._validate_unique = False
74   - super(MongoForm, self).__init__(data, None, auto_id, prefix, object_data, error_class, label_suffix, empty_permitted)
  87 + super(MongoForm, self).__init__(data, None, auto_id, prefix, object_data, \
  88 + error_class, label_suffix, empty_permitted)
75 89
76 90 def save(self, commit=True):
77 91 """save the instance or create a new one.."""

0 comments on commit 1e58f63

Please sign in to comment.
Something went wrong with that request. Please try again.