{ "info": { "author": "Thomas A. Weholt", "author_email": "thomas@weholt.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "oak\n===\n\nRapid prototyping for views, templates and models in django.\n\n Version : 0.1.1\n Status : alpha / proof-of-concept\n Code @ : http://github.com/weholt/django-oak/\n Contact : thomas@weholt.org\n\nIntroduction\n------------\n\nOak is a tool to help you get a prototype of a site up and running very fast. It takes care of configuring urls,\ncreating views and provide a basic set of templates to enable creation, deletion and removal of objects.\n\nIt might not be production-ready and serves more as a proof-of-concept project at the moment. Comments are very welcome.\n\nWhy?\n----\n\n- *DRY*. I found myself re-creating the same templates, views and urls over and over for models in my apps. My templates for \ncreate, update and delete was almost identical for 9 of 10 models. My urlpatterns followed the same pattern. And my views. \n- I wanted to build on-top of class based generic views and easily switch to full CBGV if need be.\n\nInstallation\n------------\n \n1. `pip install django-oak`\n2. Add `oak` to INSTALLED_APPS in settings.py - after all other apps to get correct template resolving.\n3. `python manage.py migrate` and `python manage.py runserver`\n\nRequirements\n------------\n\nOak assumes use of a few patterns:\n\n - urls will be created as:\n - create: '/app_label/model_name/create/$'\n - update: '/app_label/model_name/update/(?P\\d+)/$'\n - delete: '/app_label/model_name/delete/(?P\\d+)/$'\n - list: '/app_label/model_name/list/$'\n - detail: '/app_label/model_name/(?P\\d+)/$'\n \n - names of urls will be: \n - create: 'app_label-model_name-create'\n - update: 'app_label-model_name-update'\n - delete: 'app_label-model_name-delete'\n - list: 'app_label-model_name-list'\n - detail: 'app_label-model_name'\n \n - models must implement the 'get_absolute_url'-method\n\nA simple example\n----------------\n\n*NB! This alpha-release of oak assumes the user is logged in all views related to creation, updates and deletion of objects.*\n\nWe want to re-create the polls app from the django tutorial (with minor changes to illustrate some features of oak).\nCreate a new django project, create an app called polls and the following models to your polls/models.py:\n\n from django.core.urlresolvers import reverse_lazy\n from django.contrib.auth.models import User\n from django.db import models\n from oak.decorators import oakify\n \n \n @oakify.model()\n class Question(models.Model):\n creator = models.ForeignKey(User, related_name=\"questions\")\n question_text = models.CharField(max_length=200)\n pub_date = models.DateTimeField('date published')\n \n def __str__(self):\n return self.question_text\n \n def get_absolute_url(self):\n return reverse_lazy('polls-question', args=[self.id])\n \n \n @oakify.model()\n class Choice(models.Model):\n question = models.ForeignKey(Question, related_name=\"choices\")\n choice_text = models.CharField(max_length=200)\n votes = models.IntegerField(default=0)\n \n def __str__(self):\n return self.choice_text\n \n def get_absolute_url(self):\n return reverse_lazy('polls-choice', args=[self.id])\n\nA few things to notice:\n\n- `from oak.decorators import oakify` : this is the oak decorator registering the model and triggers the creation \nof required views and urls.\n- `@oakify.model()`: the actual decoration of our models.\n- both models implement `the get_absolute_url` method and return a reversed url using the patterns described above.\n\nTo get the generated urls into our project, modify your urls.py file to look like this:\n\n from django.conf.urls import patterns, include, url\n from django.contrib import admin\n import oak\n \n urlpatterns = patterns('',\n url(r'^admin/', include(admin.site.urls)),\n url(r'^', include('oak.urls')),\n )\n \nNotice that this will make every url automatically generated by oak available at root level. Finally add oak and polls\nto your installed apps in settings.py, always adding oak *after* everything else:\n\n INSTALLED_APPS = (\n 'django.contrib.admin',\n 'django.contrib.auth',\n 'django.contrib.contenttypes',\n 'django.contrib.sessions',\n 'django.contrib.messages',\n 'django.contrib.staticfiles',\n 'polls',\n 'oak',\n )\n\nNow do the `python manage.py migrate` and `python manage.py runserver` to test it. If you type in any non-existing url,\n you'll see the generated urls in the debug page:\n \n ^admin/\n ^polls/choice/(?P\\d+)/ [name='polls-choice']\n ^polls/choice/create/$ [name='polls-choice-create']\n ^polls/choice/update/(?P\\d+)/$ [name='polls-choice-update']\n ^polls/choice/delete/(?P\\d+)/$ [name='polls-choice-delete']\n ^polls/choice/list/$ [name='polls-choice-list']\n ^polls/question/(?P\\d+)/ [name='polls-question']\n ^polls/question/create/$ [name='polls-question-create']\n ^polls/question/update/(?P\\d+)/$ [name='polls-question-update']\n ^polls/question/delete/(?P\\d+)/$ [name='polls-question-delete']\n ^polls/question/list/$ [name='polls-question-list']\n\nIf you go to `/polls/question/list/` you'll be greeted with a page telling you that templates are missing - this is by design.\nYou'll have to implement the templates for list and detail views your self. Now create `polls/templates/polls/question_list.html`\nwith this content:\n\n {% extends 'base.html' %}\n {% block content %}\n Create\n
    \n {% for question in object_list %}\n
  • {{ question }}
  • \n {% endfor %}\n
\n Create choice\n {% endblock %}\n \nCreate `polls/templates/polls/question_detail.html` with this content:\n\n {% extends 'base.html' %}\n {% block content %}\n

Question #{{object.id}}: {{object.question_text}}

\n Update\n Delete\n {% endblock %}\n\n*NB! If you get any errors, try going to `/admin/` and log in before proceeding further.*\n \nNow you should be able to create, update, delete, list and view details of questions.\n\nA more advanced example\n-----------------------\n\nOn of the changes of our models compared to the standard polls app is the addition of a creator. We want this to be set\nto the user creating the questions and should not have to be entered by the user at all. Modify your models.py file and\nremove the decorations of the Question model:\n\n @oakify.model() <- Remove this line\n class Question(models.Model):\n\nIf you enter an invalid url and look at the available urlconfigurations you'll notice everyting related to Question is gone.\nIn polls/views.py add:\n\n import datetime\n from django.http import HttpResponseRedirect\n from django.views.generic import ListView, DetailView\n import oak\n from .models import *\n \n \n @oak.decorators.oakify.view()\n class QuestionView(oak.views.BaseCrudView):\n model = Question\n fields = ('question_text',)\n \n def form_valid(self, form):\n self.object = form.save(commit=False)\n # only set the following values at creation, not on updates\n if not self.object.pk: \n self.object.creator = self.request.user\n self.object.pub_date = datetime.date.today()\n self.object.save()\n return HttpResponseRedirect(self.target_url or self.get_success_url())\n \n def get_success_url(self):\n return reverse_lazy('polls-question-list')\n \n \n @oak.decorators.oakify.view()\n class QuestionListView(ListView):\n model = Question\n queryset = Question.objects.all()\n \n \n @oak.decorators.oakify.view()\n class QuestionDetailView(DetailView):\n model = Question\n\nThe first view subclasses BaseCrudView and it will handle create, update and delete operations related to your model. \nImplementing `form_valid` method handles setting the creator-field of a question to the user object of the logged in user.\nIt also sets the pub_date-field to today.\n\nThe two next views handles the list and detail views. \n\nAdding your own templates\n-------------------------\n\nOak will look for matching templates in your apps template folders before defaulting to its own base templates. So to add\n your own templates simply create a folderstructure like `templates/app_label/model_name/.html` in your app folder.\nChange `` to one of the following; create, update, delete, detail or list.\n\nLicense\n-------\nOak is released under a BSD license.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/weholt/django-oak", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "django-oak", "package_url": "https://pypi.org/project/django-oak/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-oak/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/weholt/django-oak" }, "release_url": "https://pypi.org/project/django-oak/0.1.2/", "requires_dist": null, "requires_python": null, "summary": "Rapid prototyping for views and models in django.", "version": "0.1.2" }, "last_serial": 1279094, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "8b063bf40ae697723a97824045b09947", "sha256": "53c28a2a4f9cbc4a8eda3af08c528827f371e9dec82c3a93f086790c93e50dd3" }, "downloads": -1, "filename": "django-oak-0.1.0.tar.gz", "has_sig": false, "md5_digest": "8b063bf40ae697723a97824045b09947", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10579, "upload_time": "2014-10-22T16:39:38", "url": "https://files.pythonhosted.org/packages/cf/cf/f3b55f5c06debfebfbfea982cfccf47d0da46ee43ab78d4cff5df4dda5f3/django-oak-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "1568814335b6092608403396b1d226ee", "sha256": "ccb03bd93ab77dc5034f9b092ac2e225bf461c6a8c0e9513a9246e3a74f79d03" }, "downloads": -1, "filename": "django-oak-0.1.1.tar.gz", "has_sig": false, "md5_digest": "1568814335b6092608403396b1d226ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10592, "upload_time": "2014-10-22T16:42:53", "url": "https://files.pythonhosted.org/packages/19/d0/a59dd8623765aca7910540aa39b4e08b3c9d0ae658cc7be9da0116890c7c/django-oak-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "7fbabd90aa6f4e3d3c7ee0e0efde754c", "sha256": "7429a3df0c4e56835869401b32ed34967b91251d93b2f74d526f6f293da15aa8" }, "downloads": -1, "filename": "django-oak-0.1.2.tar.gz", "has_sig": false, "md5_digest": "7fbabd90aa6f4e3d3c7ee0e0efde754c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7689, "upload_time": "2014-10-22T16:47:31", "url": "https://files.pythonhosted.org/packages/18/a3/3288a530fec8b890af6c28c73b60105d0952a3939d6d56627196170531d7/django-oak-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7fbabd90aa6f4e3d3c7ee0e0efde754c", "sha256": "7429a3df0c4e56835869401b32ed34967b91251d93b2f74d526f6f293da15aa8" }, "downloads": -1, "filename": "django-oak-0.1.2.tar.gz", "has_sig": false, "md5_digest": "7fbabd90aa6f4e3d3c7ee0e0efde754c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7689, "upload_time": "2014-10-22T16:47:31", "url": "https://files.pythonhosted.org/packages/18/a3/3288a530fec8b890af6c28c73b60105d0952a3939d6d56627196170531d7/django-oak-0.1.2.tar.gz" } ] }