├── 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 |
10 | {% csrf_token %} 11 | 12 | {{ form }} 13 |
14 |

| Cancel

15 |
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 | --------------------------------------------------------------------------------