├── requirements.txt
├── tekextensions
├── models.py
├── __init__.py
├── templates
│ ├── addnew.html
│ └── popup.html
├── context_processors.py
├── forms.py
├── views.py
└── widgets.py
├── .gitignore
├── setup.py
└── README.markdown
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django>=1.5
--------------------------------------------------------------------------------
/tekextensions/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.pyo
3 | *.db
4 | *.swp
5 | .idea
6 | local_settings.py
7 | haystack/
8 |
--------------------------------------------------------------------------------
/tekextensions/__init__.py:
--------------------------------------------------------------------------------
1 | VERSION = (0, 0, 3)
2 | __version__ = '.'.join(map(str, VERSION))
3 |
--------------------------------------------------------------------------------
/tekextensions/templates/addnew.html:
--------------------------------------------------------------------------------
1 | +
5 |
--------------------------------------------------------------------------------
/tekextensions/templates/popup.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 | Add {{ field }}
5 |
6 |
7 |
8 | Add {{ field }}
9 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tekextensions/context_processors.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.contrib.sites.models import Site, RequestSite
3 |
4 |
5 | def admin_media_prefix(request):
6 | return {'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX }
7 |
8 |
9 | def current_site(request):
10 | """
11 | A context processor to add the "current_site" to the current Context
12 |
13 | """
14 |
15 | context_name = 'CURRENT_SITE'
16 |
17 | try:
18 | current_site = Site.objects.get_current()
19 | return { context_name: current_site, }
20 | except Site.DoesNotExist:
21 | # always return a dict, no matter what!
22 | return { context_name: RequestSite(request)}
23 |
--------------------------------------------------------------------------------
/tekextensions/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms.models import modelform_factory
2 | from django.db.models.loading import get_models, get_apps
3 |
4 |
5 | def normalize_model_name(model_name):
6 | if model_name.lower() == model_name:
7 | normal_model_name = model_name.capitalize()
8 | else:
9 | normal_model_name = model_name
10 |
11 | return normal_model_name
12 |
13 |
14 | def get_model_form(model_name):
15 | app_list = get_apps()
16 | for app in app_list:
17 | for model in get_models(app):
18 | if model.__name__ == model_name:
19 | form = modelform_factory(model)
20 | return form
21 |
22 | raise Exception('Did not find the model %s' % model_name)
23 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | try:
2 | from setuptools import setup
3 | except ImportError:
4 | from distutils.core import setup
5 |
6 | setup(
7 | name='django-tekextensions',
8 | version=__import__('tekextensions').__version__,
9 | description='A set of re-usable widgets and commands for django',
10 | long_description='',
11 | author='John Anderson',
12 | author_email='sontek@gmail.com',
13 | url='http://github.com/sontek/django-tekextensions',
14 | download_url='http://github.com/sontek/django-tekextensions',
15 | license='BSD',
16 | packages=['tekextensions'],
17 | classifiers = [
18 | 'Framework :: Django',
19 | 'License :: OSI Approved :: BSD License',
20 | 'Operating System :: OS Independent',
21 | 'Programming Language :: Python',
22 | ],
23 | )
24 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | admin popups
2 | ====================
3 | > if using grappeli, copy RelatedObjectLookups.js to your admin_media folder from django's admin media
4 |
5 | settings.py
6 | --------------------
7 | TEMPLATE_CONTEXT_PROCESSORS = (
8 | 'tekextensions.context_processors.admin_media_prefix',
9 | )
10 | INSTALLED_APPS = (
11 | 'tekextensions',
12 | )
13 |
14 | urls.py
15 | --------------------
16 | url(r'^add/(?P\w+)/?$', 'tekextensions.views.add_new_model'),
17 |
18 | forms.py
19 | --------------------
20 | >override any ModelChoiceField widget with SelectWithPopUp
21 |
22 | from tekextensions.widgets import SelectWithPopUp
23 | from django import forms
24 |
25 | class CustomForm(forms.Form):
26 | company = forms.ModelChoiceField(CustomModel.objects, widget=SelectWithPopUp)
27 |
--------------------------------------------------------------------------------
/tekextensions/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from django.http import HttpResponse
4 | from django.utils.html import escape
5 | from django.forms import ValidationError
6 | from tekextensions.forms import get_model_form, normalize_model_name
7 |
8 |
9 | def add_new_model(request, model_name, form=None):
10 | normal_model_name = normalize_model_name(model_name)
11 |
12 | if not form:
13 | form = get_model_form(normal_model_name)
14 |
15 | if request.method == 'POST':
16 | form = form(request.POST)
17 | if form.is_valid():
18 | try:
19 | new_obj = form.save()
20 | except ValidationError as error:
21 | new_obj = None
22 |
23 | if new_obj:
24 | return HttpResponse(
25 | '' %
26 | (escape(new_obj._get_pk_val()), escape(new_obj)))
27 |
28 | else:
29 | form = form()
30 |
31 | page_context = {'form': form, 'field': normal_model_name}
32 | return render_to_response('popup.html', page_context, context_instance=RequestContext(request))
--------------------------------------------------------------------------------
/tekextensions/widgets.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.template.loader import render_to_string
3 | from django.contrib.admin.widgets import FilteredSelectMultiple
4 |
5 |
6 | class PopUpBaseWidget(object):
7 | def __init__(self, model=None, template='addnew.html', *args, **kwargs):
8 | self.model = model
9 | self.template = template
10 | super(PopUpBaseWidget, self).__init__(*args, **kwargs)
11 |
12 | def render(self, name, *args, **kwargs):
13 | html = super(PopUpBaseWidget, self).render(name, *args, **kwargs)
14 |
15 | if not self.model:
16 | self.model = name
17 |
18 | popupplus = render_to_string(self.template, {'field': name, 'model': self.model})
19 | return html+popupplus
20 |
21 | def _media(self):
22 | js = ["admin/js/core.js", "admin/js/admin/RelatedObjectLookups.js"]
23 |
24 | return forms.widgets.Media(
25 | js=js
26 | )
27 | media = property(_media)
28 |
29 |
30 | class FilteredMultipleSelectWithPopUp(PopUpBaseWidget, FilteredSelectMultiple):
31 | pass
32 |
33 |
34 | class MultipleSelectWithPopUp(PopUpBaseWidget, forms.SelectMultiple):
35 | pass
36 |
37 |
38 | class SelectWithPopUp(PopUpBaseWidget, forms.Select):
39 | pass
40 |
--------------------------------------------------------------------------------