| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- from django.contrib.contenttypes.models import ContentType
- from django.urls.base import reverse
- from django.db import transaction
- from django.db.models import Q
- from django.forms import ModelChoiceField
- from django.http import QueryDict
- from django.template import loader
- from django.utils.decorators import method_decorator
- from django.utils.encoding import smart_text
- from django.utils.translation import ugettext_lazy as _
- from django.views.decorators.csrf import csrf_protect
- from xadmin.filters import FILTER_PREFIX, SEARCH_VAR
- from xadmin.plugins.relate import RELATE_PREFIX
- from xadmin.plugins.utils import get_context_dict
- from xadmin.sites import site
- from xadmin.views import ModelAdminView, BaseAdminPlugin, ListAdminView
- from xadmin.views.list import COL_LIST_VAR, ORDER_VAR
- from xadmin.views.dashboard import widget_manager, BaseWidget, PartialBaseWidget
- from xadmin.models import Bookmark
- csrf_protect_m = method_decorator(csrf_protect)
- class BookmarkPlugin(BaseAdminPlugin):
- # [{'title': "Female", 'query': {'gender': True}, 'order': ('-age'), 'cols': ('first_name', 'age', 'phones'), 'search': 'Tom'}]
- list_bookmarks = []
- show_bookmarks = True
- def has_change_permission(self, obj=None):
- if not obj or self.user.is_superuser:
- return True
- else:
- return obj.user == self.user
- def get_context(self, context):
- if not self.show_bookmarks:
- return context
- bookmarks = []
- current_qs = '&'.join([
- '%s=%s' % (k, v)
- for k, v in sorted(filter(
- lambda i: bool(i[1] and (
- i[0] in (COL_LIST_VAR, ORDER_VAR, SEARCH_VAR)
- or i[0].startswith(FILTER_PREFIX)
- or i[0].startswith(RELATE_PREFIX)
- )),
- self.request.GET.items()
- ))
- ])
- model_info = (self.opts.app_label, self.opts.model_name)
- has_selected = False
- menu_title = _(u"Bookmark")
- list_base_url = reverse('xadmin:%s_%s_changelist' %
- model_info, current_app=self.admin_site.name)
- # local bookmarks
- for bk in self.list_bookmarks:
- title = bk['title']
- params = dict([
- (FILTER_PREFIX + k, v)
- for (k, v) in bk['query'].items()
- ])
- if 'order' in bk:
- params[ORDER_VAR] = '.'.join(bk['order'])
- if 'cols' in bk:
- params[COL_LIST_VAR] = '.'.join(bk['cols'])
- if 'search' in bk:
- params[SEARCH_VAR] = bk['search']
- def check_item(i):
- return bool(i[1]) or i[1] == False
- bk_qs = '&'.join([
- '%s=%s' % (k, v)
- for k, v in sorted(filter(check_item, params.items()))
- ])
- url = list_base_url + '?' + bk_qs
- selected = (current_qs == bk_qs)
- bookmarks.append(
- {'title': title, 'selected': selected, 'url': url})
- if selected:
- menu_title = title
- has_selected = True
- content_type = ContentType.objects.get_for_model(self.model)
- bk_model_info = (Bookmark._meta.app_label, Bookmark._meta.model_name)
- bookmarks_queryset = Bookmark.objects.filter(
- content_type=content_type,
- url_name='xadmin:%s_%s_changelist' % model_info
- ).filter(Q(user=self.user) | Q(is_share=True))
- for bk in bookmarks_queryset:
- selected = (current_qs == bk.query)
- if self.has_change_permission(bk):
- change_or_detail = 'change'
- else:
- change_or_detail = 'detail'
- bookmarks.append({'title': bk.title, 'selected': selected, 'url': bk.url, 'edit_url':
- reverse('xadmin:%s_%s_%s' % (bk_model_info[0], bk_model_info[1], change_or_detail),
- args=(bk.id,))})
- if selected:
- menu_title = bk.title
- has_selected = True
- post_url = reverse('xadmin:%s_%s_bookmark' % model_info,
- current_app=self.admin_site.name)
- new_context = {
- 'bk_menu_title': menu_title,
- 'bk_bookmarks': bookmarks,
- 'bk_current_qs': current_qs,
- 'bk_has_selected': has_selected,
- 'bk_list_base_url': list_base_url,
- 'bk_post_url': post_url,
- 'has_add_permission_bookmark': self.admin_view.request.user.has_perm('xadmin.add_bookmark'),
- 'has_change_permission_bookmark': self.admin_view.request.user.has_perm('xadmin.change_bookmark')
- }
- context.update(new_context)
- return context
- # Media
- def get_media(self, media):
- return media + self.vendor('xadmin.plugin.bookmark.js')
- # Block Views
- def block_nav_menu(self, context, nodes):
- if self.show_bookmarks:
- nodes.insert(0, loader.render_to_string('xadmin/blocks/model_list.nav_menu.bookmarks.html',
- context=get_context_dict(context)))
- class BookmarkView(ModelAdminView):
- @csrf_protect_m
- @transaction.atomic
- def post(self, request):
- model_info = (self.opts.app_label, self.opts.model_name)
- url_name = 'xadmin:%s_%s_changelist' % model_info
- bookmark = Bookmark(
- content_type=ContentType.objects.get_for_model(self.model),
- title=request.POST[
- 'title'], user=self.user, query=request.POST.get('query', ''),
- is_share=request.POST.get('is_share', 0), url_name=url_name)
- bookmark.save()
- content = {'title': bookmark.title, 'url': bookmark.url}
- return self.render_response(content)
- class BookmarkAdmin(object):
- model_icon = 'fa fa-book'
- list_display = ('title', 'user', 'url_name', 'query')
- list_display_links = ('title',)
- user_fields = ['user']
- hidden_menu = True
- def queryset(self):
- if self.user.is_superuser:
- return Bookmark.objects.all()
- return Bookmark.objects.filter(Q(user=self.user) | Q(is_share=True))
- def get_list_display(self):
- list_display = super(BookmarkAdmin, self).get_list_display()
- if not self.user.is_superuser:
- list_display.remove('user')
- return list_display
- def has_change_permission(self, obj=None):
- if not obj or self.user.is_superuser:
- return True
- else:
- return obj.user == self.user
- @widget_manager.register
- class BookmarkWidget(PartialBaseWidget):
- widget_type = _('bookmark')
- widget_icon = 'fa fa-bookmark'
- description = _(
- 'Bookmark Widget, can show user\'s bookmark list data in widget.')
- template = "xadmin/widgets/list.html"
- bookmark = ModelChoiceField(
- label=_('Bookmark'), queryset=Bookmark.objects.all(), required=False)
- def setup(self):
- BaseWidget.setup(self)
- bookmark = self.cleaned_data['bookmark']
- model = bookmark.content_type.model_class()
- data = QueryDict(bookmark.query)
- self.bookmark = bookmark
- if not self.title:
- self.title = smart_text(bookmark)
- req = self.make_get_request("", data.items())
- self.list_view = self.get_view_class(
- ListAdminView, model, list_per_page=10, list_editable=[])(req)
- def has_perm(self):
- return True
- def context(self, context):
- list_view = self.list_view
- list_view.make_result_list()
- base_fields = list_view.base_list_display
- if len(base_fields) > 5:
- base_fields = base_fields[0:5]
- context['result_headers'] = [c for c in list_view.result_headers(
- ).cells if c.field_name in base_fields]
- context['results'] = [
- [o for i, o in enumerate(filter(
- lambda c: c.field_name in base_fields,
- r.cells
- ))]
- for r in list_view.results()
- ]
- context['result_count'] = list_view.result_count
- context['page_url'] = self.bookmark.url
- site.register(Bookmark, BookmarkAdmin)
- site.register_plugin(BookmarkPlugin, ListAdminView)
- site.register_modelview(r'^bookmark/$', BookmarkView, name='%s_%s_bookmark')
|