Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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