Code Monkey home page Code Monkey logo

django-tabbed-admin's Introduction

PyPI version build-status coverage

Django tabbed admin

Simple library to easilly add tabs to admin forms. It also allows users to re-order inlines and fieldsets. Django tabbed admin is compatible with django-grappelli and django-gipsy.

https://box.everhelper.me/attachment/256054/rSqCFM20d245qFlG5z64EgiOVpeuTU3P/341506-h1u4JrpaUan0tG2e/screen.png

Grappelli:

https://box.everhelper.me/attachment/256057/rSqCFM20d245qFlG5z64EgiOVpeuTU3P/341506-kQnZXKsO0pfrU4cI/screen.png

Install

It is strongly recommanded to install this theme from GIT with PIP onto you project virtualenv.

From PyPi

pip install django-tabbed-admin

From Github

https://github.com/omji/django-tabbed-admin#egg=tabbed_admin

setup

Simply add the app in your installed apps list in settings.py

INSTALLED_APPS = (
    ...
    'tabbed_admin'
    ...
)

Django-tabbed-admin by default requires Jquery UI tabs plugin in order to work. It is packaged with the static files required to make it funcitonnal, however, they are not activated by default to avoid a conflict with other libraries.

In order to activate the Jquery UI statics, add the following line to the project settings:

TABBED_ADMIN_USE_JQUERY_UI = True

Configure admin tabs

In order to add tabs to a model admin, it should inherit from tabbed_admin.TabbedModelAdmin and contain a tabs attribute. The tab attribute configuration tries to remain similar to the fieldsets and inlines setup logic.

Basically, a tuple can be created for each tab exactely the same way as for fieldsets, except that inlines can be added anywhere in between.

tab_overview = (
    (None, {
        'fields': ('name', 'bio', 'style')
    }),
    MusicianInline,
    ('Contact', {
        'fields': ('agent', 'phone', 'email')
    })
)

Then each tuple have to be passed to a tabs attribute prefixed by the verbose name to display within the tab:

tabs = [
    ('Overview', tab_overview),
    ('Albums', tab_album)
]

A full example would give:

from django.contrib import admin

from tabbed_admin import TabbedModelAdmin
from .models import Band, Musician, Album


class MusicianInline(admin.StackedInline):
    model = Musician
    extra = 1


class AlbumInline(admin.TabularInline):
    model = Album
    extra = 1


@admin.register(Band)
class BandAdmin(TabbedModelAdmin):
    model = Band

    tab_overview = (
        (None, {
            'fields': ('name', 'bio', 'style')
        }),
        MusicianInline,
        ('Contact', {
            'fields': ('agent', 'phone', 'email')
        })
    )
    tab_album = (
        AlbumInline,
    )
    tabs = [
        ('Overview', tab_overview),
        ('Albums', tab_album)
    ]

Configure tabs dynamically

Be warned that the tabs will completely reset the fieldsets and inlines attributes in order to avoid conflicts during the form saving. Both attributes are overwritten with the entries passed to the tabs attribute. For the same reasons, it is highly recommanded not to overwrite get_fieldsets or get_inlines.

You can pass and modify the tabs dynamically the same way you would do for fieldsets or inlines.

def get_tabs(self, request, obj=None):
    tabs = self.tabs
    if obj is not None:
        tab_overview = self.tab_overview + ('Social', {
            'fields': ('website', 'twitter', 'facebook')
        })
        tab_ressources = self.tab_ressources + (InterviewInline, )
        tabs = [
            ('Overview', tab_overview),
            ('Ressources', tab_ressources)
        ]
    self.tabs = tabs
    return super(BandAdmin, self).get_tabs(request, obj)

Change the jquery ui

You can change the jquery ui css and js by either overriding the media in the admin class

class Media:
    css = {
        'all': ('css/jquery-ui.theme.min.css',)
    }

or by changing the the following settings,

TABBED_ADMIN_JQUERY_UI_CSS and TABBED_ADMIN_JQUERY_UI_JS

TABBED_ADMIN_JQUERY_UI_CSS = 'static/css/my-custom-jquery-ui.css'
TABBED_ADMIN_JQUERY_UI_JS = 'static/js/my-custom-jquery-ui.js'

Contribution

Please feel free to contribute. Any help and advices are much appreciated. You will find an example application to run and develop the library easily.

LINKS

Development:
https://github.com/omji/django-tabbed-admin
Package:
https://pypi.python.org/pypi/django-tabbed-admin

django-tabbed-admin's People

Contributors

arthexis avatar erikw avatar internaut avatar jox avatar jsoa avatar ogtony avatar omji avatar tomatohater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-tabbed-admin's Issues

Django 2.0 compatibility

Tabbed admin isn't working with Django 2.0. Probably because TabbedAdmin uses django.forms.Media.add_css() and django.forms.Media.add_js() functions, which do not exist in Django 2.0.

Question - are there any plans on making TabbedAdmin compatible with Django 2.0?

Tab links are not generated from tab names

Let's suppose we have 3 tabs:
"About", "Projects", "Contacts"

If we click on the first tab, the admin url change to /#tabs-1, but I think it should be: /#about.

Each tab link should be generated using the django slugify function.

JS does not work without grappelli

Hi!

I installed the app as explained in the README but I obtain the following error in the Firefox console:

TypeError: $(...).tabs is not a function[Learn More]  change:523:21
	<anonymous> http://127.0.0.1:8000/admin/members/member/2/change/:523:21
	<anonymous> http://127.0.0.1:8000/admin/members/member/2/change/:521:18

change:523 :

$('#tabs').tabs({

When I install Grappelli, it works, but I don't want it.

I am using Firefox 51.0.1 on ArchLinux, Django 1.10, Python 3.6 and django-tabbed-admin 1.0.1.

Thanks a lot.

PS: I also have these CSS warnings:

Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:548
Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:4310
Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:4460
Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:4535
Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:15006
Expected ‘none’, URL, or filter function but found ‘Alpha(’.  Error in parsing value for ‘filter’.  Declaration dropped.  jquery-ui-1.11.4.min.css:7:15171

Missing horizontal scrollbar when using TabularInline with many fields

Thanks for great django plugin, i love it!

I have an issue with how TabularInline with many fields is displayed.

Without tabs, there is a horizontal scrollbar on the lower edge of browser window.
When i add tabs, this scrollbar goes missing and i have no way of displaying fields that don't fit on the screen.
I can use StackedInline to mitigate this, but tabular view is so much better suited for this particular usecase.

What might be the problem? Is there a way to fix this?
Thanks!

Not working without grappelli

If you don't have grappelli installed, then there will be a KeyError. In tabbed_admin/admin.py there is

    def media(self):
        css = {}

        if 'grappelli' in settings.INSTALLED_APPS:
            css['all'] = ("tabbed_admin/css/tabbed_grappelli_admin.css", )

        if USE_JQUERY_UI:
            css['all'] = \
                ("tabbed_admin/css/jquery-ui-1.11.4.min.css",
"tabbed_admin/css/tabbed_admin.css", ) + css['all']

On the last line we try to fetch css['all'] which does not exist unless we entered the if-grappelli.

still not working in django 2.0

Hi, i just used your latest version (django-tabbed-admin 1.0.4) in django 2.0 but the tabs do not display.
I used the same on a django 1.11 project and the tabs display fine, however in django 2.0 it still not displaying the tabs, i just see a long form.

Kindly help please.

Admin `collapse` does not work like in the fieldsets

In a django fieldset, if you define the collapse class, it would enable a hide/show functionality. But that doesnt happen with the tabs.

Here is the example of one of my tabs:

tab_overview=(
      (None,{
          'fields':('end_dt','name',),
          }),  
      ('Extra',{'fields':('start_dt',),
        'classes': ['collapse']}),
      )  
  

The html does get the collapse:

<fieldset class="module aligned collapse">
    <h2>Extra</h2>
    
    
        <div class="form-row field-start_dt">
            
            
                <div>
                    
                    
                        <label class="required" for="id_start_dt">Start Date:</label>
                        
                            <input type="text" name="start_dt" value="2018-09-09" class="vDateField" size="10" required="" id="id_start_dt"><span class="datetimeshortcuts">&nbsp;<a href="#">Today</a>&nbsp;|&nbsp;<a href="#" id="calendarlink0"><span class="date-icon" title="Choose a Date"></span></a></span>
                        
                    
                    
                <br><span class="timezonewarning">Note: You are 3 hours behind server time.</span></div>
            
        </div>
    
</fieldset>

But it doesn have the hide/show functionality

Problems with django-nested-admin

The Nested admin inline not allowed to add new lines is drawn correctly.

Example:
settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tabbed_admin',
    'nested_admin',
    'smart_selects',
]

urls.py


from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include

urlpatterns = [
    url(r'^nested_admin/', include('nested_admin.urls')),
    url(r'^admin/', admin.site.urls),
    url(r'^chaining/', include('smart_selects.urls')),
]

models.py

from smart_selects.db_fields import ChainedForeignKey 

class Continent(models.Model):
    name = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name


class Country(models.Model):
    continent = models.ForeignKey(Continent)
    name = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name


class TableOfContents(models.Model):
    tabla = models.CharField(max_length=200)
    fecha = models.DateTimeField('Fecha de publicacion')

    def __unicode__(self):
        return self.tabla


class TocSection(models.Model):
    tabla = models.ForeignKey(TableOfContents)
    seccion = models.CharField(max_length=200)
    position = models.IntegerField()

    def __unicode__(self):
        return self.seccion

class TocArticle(models.Model):
    section = models.ForeignKey(TocSection)
    position = models.IntegerField()
    continent = models.ForeignKey(Continent, blank=True, null=True)
    country = ChainedForeignKey(Country, chained_field="continent",chained_model_field="continent", 
		show_all=False, auto_choose=True, sort=True, blank=True, null=True)
    city = models.CharField(max_length=50, default='Olvera')
    street = models.CharField(max_length=100, default='Pozo')

    def __unicode__(self):
        return self.city

admin.py

from django.contrib import admin

# An example admin.py for a Table of Contents app

from django.contrib import admin
import nested_admin
from tabbed_admin import TabbedModelAdmin

from .models import *

class TocArticleInline(nested_admin.NestedTabularInline):
    model = TocArticle
    sortable_field_name = "position"
    extra = 0

class TocSectionInline(nested_admin.NestedTabularInline):
    model = TocSection
    # sortable_field_name = "position"
    extra = 0
    inlines = [TocArticleInline]
    classes = ('collapse',)

class TableOfContentsAdmin(TabbedModelAdmin, nested_admin.NestedModelAdmin): 
    tab_info = (('Datos varios', {'fields': ('fecha', 'tabla',)}),)
    tab_secciones = (TocSectionInline, ) 
    tabs = [
        ('Datos Generales', tab_info),
        ('Secciones', tab_secciones),
    ]
    #inlines = [TocSectionInline, ]

admin.site.register(TableOfContents, TableOfContentsAdmin)
admin.site.register(Continent)
admin.site.register(Country)

Replace tabs nav with a select in responsive layout

Hi,
I added it to an existing project where I have about 10 tabs, and when the admin become responsive, the tabs still work but the layout breaks on multi-lines.

Here there are 3 solutions:

  • Display only icons in tabs (this can be done easily passing safe html to the tab label, but in my case there are too many tabs and it is not enough)
  • Allow horinzontal scrolling for the tabs nav (not very intuitive to use)
  • Replace tabs nav with a select (I think this is the best solution)

What do you think about it?

PS. thank you for this great lib, it's very easy to configure and it works very well. I choosed it as my favorite admin tabs library and I added html/css support to django-admin-interface

Feature Request. Custom html tab templates

Good day,

Thank you for the awesome plugin. It really works great.

One feature that can be really nice is to be able to link a tab to a custom html template.

Something like:

tabs = [
    ('Summary', "/admin/.../summary_tab.html"),
    ('Personal', tab_overview),
    ('Personal Docs', tab_personal_doc),
    ('Contact Details', tab_contact),
    ('Company Details', tab_company)
]

Unable to get tabbed-admin working

Hi.
I'm unable to get tabbed-admin working.
No python errors, no javascript errors, jquery ui correctly loaded ... but simply I can't see any tab.
I've added tabbed_admin to INSTALLED_APPS, set TABBED_ADMIN_USE_JQUERY_UI to True, my model admin class is inheriting from TabbedModelAdmin and has a 'tabs' attribute.
Am I missing something? I'm using Django 1.9.7

Thanks

Foreign Key adding in same tab

When I try to add another foreign key object in tabbed model admin (by pressing that + on foreign key widget) I get that new object admin page opened in the same tab, not in the new popup window as expected
Django 1.9
tabbed-admin 1.0.1

Uncaught TypeError: $(...).tabs is not a function

The error "Uncaught TypeError: $(...).tabs is not a function" is produced when using django-tabbed-admin under the following setup:

  • Django = 1.10.5
  • django-tabbed-admin=1.0.4
  • DEFAULT_JQUERY_UI_JS = 'tabbed_admin/js/jquery-ui-1.11.4.min.js'

The problem is that the code in jquery-ui-1.11.4.min.js is as follows:

/*! jQuery UI - v1.11.4 - 2015-07-27
(...)
jQuery = jQuery \|\| django.jQuery.noConflict(false); 

and the code on django-tabbed-admin uses it this way (change_form.html):

    <script type="text/javascript">
        (function($) {
            $(window).scrollTop()
            $('#tabs').tabs({
                {% if add %}
                // when adding, don't select a tab by default, we'll do it ourselves
                // by finding the first available tab.
                selected: -1
                {% endif %}
            });
        (....)
        })(django.jQuery);
    </script>
    <!-- end admin_tabs stuff -->

To sort this out this should be what would be passed in to the IIFE instead of the (django.jQuery) as above:

    <script type="text/javascript">
        (function($) {
            (....)
        })((typeof window.jQuery == 'undefined' && typeof window.django != 'undefined')
  ? django.jQuery
  : jQuery)
    </script>
    <!-- end admin_tabs stuff -->

as is the code used in, eg., django-extensions - see this.

I've created a PR to solve this issue. Waiting for it to be included in the project.
Cheers

KeyError 'some_field_for_form_a' is not found in FormB during concurrent requests

Hello everyone. I am posting this because I am out of ideas. I have tried to find the cause of this issue for the last 2 years.

Say I have 4 model admins:

TabbedAdminMixin, ModelAdmin
a: BasketAdmin
b: ConsumerAdmin

Normal Django ModelAdmin
c: RoleAdmin
d: BranchAdmin

It took me veeeery long to be able to find a way to re-create this error but as of yesterday, I can easily re-create it by using locust to simulate concurrent requests.

When I run locust with 5 concurrent users, each doing requests to /basket//change/ and /consumer//change/ I get a keyerror where render_tab_fieldsets_inlines want to create a, for example, BasketAdmin with fields from ConsumerAdmin's form and vice versa.

When I run the same locust file on /role//change/ and /branch//change/ (vanilla django modeladmins) I don't get keyerrors. This happend locally with runserver and in production with uwsgi.

Any help will be very much appreciated!

name of parent admin form

Hi, first thanks for this useful module.
This message is rather a quote for a enhancement question than a real issue.

Your base change_form.html is placed in a tabbed_admin/ subdirectory, I was wondering why this template directory differs from the classic django base 'admin/change_form.html.

For information, I override your template in my app, and now I have to make possible to final user not to use tabbed_admin (because I am working on enabling integration of my BO into a CMS such as django-cms but still be able to run as standalone). So the less 'required' dependencies, the better, I guess.
I so override (tabbed_admin/change_form.html), but of course, when disabling your module, the parent template is not found.

Django Tabbed Admin fail when has_change_permission is false

I have an admin class like this:

from tabbed_admin.admin import TabbedModelAdmin
class mlp(TabbedModelAdmin):
    model=Book
    tab_overview=(        
       ("",{"fields": ('name','status',),}), 
    ) 
    tabs=(
        ('Overview',tab_overview), 
        )

    def has_change_permission(self, request, obj=None):
        return False

When I try to open that in admin, I get:

"Key 'name' not found in 'BookForm'. Choices are: ."

Any idea what it may be? It works fine with the has_add/delete_permission.

Tks

get_tabs is caching with server start

So I'm changing tabs dynamically like so:

def get_tabs(self, request, obj=None):
        tabs = self.tabs
        if obj and request.user != obj.created_by:
            tabs = [
                (u'Podstawowe dane', self.tab_main),
                (u'Pytania', self.tab_questions),
                (u'Tokeny', self.tab_tokens)
            ]

        self.tabs = tabs
        return super(PollAdmin, self).get_tabs(request, obj)

and when i run server and go to change view of my model it's cached with these three tabs for all users, it's omitting my base tabs config even if the condition is false

tabs = [
        (u'Podstawowe dane', tab_main),
        (u'Pytania', tab_questions),
        (u'Tokeny', tab_tokens),
        (u'Uprawnienia', tab_permissions)
    ]

Alternate CSS for use with grappelli

Not sure how you could package alternate static files for different admin styles... but this is what i use to make it look nicer with grappelli.

selection_026

from tabbed_admin import TabbedModelAdmin as TabbedModelAdminBase

class TabbedModelAdmin(TabbedModelAdminBase):
    """
    Subclass including some CSS fixes for grappelli.
    """
    class Media:
        css = {
            'all':  ('core/css/tabbed-admin.css',)
        }
.ui-tabs {
    background-color: white;
    border: 0;
    min-width: 960px;
}

.ui-widget textarea,
.ui-widget input,
.ui-widget select {
    font-family: Arial, sans-serif;
}

.ui-widget {
    font-family: Arial, sans-serif;
    font-size: 1em;
}

.ui-tabs .ui-tabs-panel {
    background-color: white;
    padding: 5px 4px 0;
}

.ui-tabs .ui-tabs-anchor {
    font-size: 9pt
}

.ui-widget-content {
    background: none;
}

.ui-tabs .ui-widget-content a {
    color: #309BBF;
}

.ui-tabs .ui-widget-content a:hover {
    color: #444;
}

.ui-tabs .ui-widget-header {
    background-image: linear-gradient(#E5E5E5, #DBDBDB);
}

.ui-tabs .ui-state-default {
    background-image: linear-gradient(#CEE9F2, #E1F0F5);
}

.ui-tabs .ui-state-active {
    background-image: linear-gradient(#CEE9F2, #fff);
    border-color: #BBB;
}

.ui-tabs .ui-state-active a {
    color: #444;
}

Django 2.0 compatibility issue with RequestContext

Today i was trying tabbed admin with Django 2.0.7 and i got this error:

Exception Type: | TypeError
context must be a dict rather than RequestContext.

Exception Location:
djangostack-2.0.7-0/apps/django/lib/python3.6/site-packages/Django-2.0.7-py3.6.egg/django/template/context.py in make_context, line 274

It seems the whole issue starts from here
/tabbed_admin/templatetags/tabbed_admin_tags.py in render_tab_fieldsets_inlines:
at line 40 shown below:

39 context["fieldset"] = f
40 return render_to_string(template, context)
41 elif entry['type'] == 'inline':

Kindly help, i dont know how to fix this. Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.