# coding=UTF-8
from itertools import chain
from django.urls.base import reverse
from django.db.models.options import PROXY_PARENTS
from django.utils import six
from django.utils.encoding import force_text
from django.utils.encoding import smart_str
from django.utils.safestring import mark_safe
from django.db.models.sql.query import LOOKUP_SEP
from django.utils.translation import ugettext as _
from django.db import models
from xadmin.sites import site
from xadmin.views import BaseAdminPlugin, ListAdminView, CreateAdminView, UpdateAdminView, DeleteAdminView
from xadmin.util import is_related_field2
RELATE_PREFIX = '_rel_'
class RelateMenuPlugin(BaseAdminPlugin):
related_list = []
use_related_menu = True
def _get_all_related_objects(self, local_only=False, include_hidden=False,
include_proxy_eq=False):
"""
Returns a list of related fields (also many to many)
:param local_only:
:param include_hidden:
:return: list
"""
include_parents = True if local_only is False else PROXY_PARENTS
fields = self.opts._get_fields(
forward=False, reverse=True,
include_parents=include_parents,
include_hidden=include_hidden
)
if include_proxy_eq:
children = chain.from_iterable(c._relation_tree
for c in self.opts.concrete_model._meta.proxied_children
if c is not self.opts)
relations = (f.remote_field for f in children
if include_hidden or not f.remote_field.field.remote_field.is_hidden())
fields = chain(fields, relations)
return list(fields)
def get_related_list(self):
if hasattr(self, '_related_acts'):
return self._related_acts
_related_acts = []
for rel in self._get_all_related_objects():
if self.related_list and (rel.get_accessor_name() not in self.related_list):
continue
if rel.related_model not in self.admin_site._registry.keys():
continue
has_view_perm = self.has_model_perm(rel.related_model, 'view')
has_add_perm = self.has_model_perm(rel.related_model, 'add')
if not (has_view_perm or has_add_perm):
continue
_related_acts.append((rel, has_view_perm, has_add_perm))
self._related_acts = _related_acts
return self._related_acts
def related_link(self, instance):
links = []
for rel, view_perm, add_perm in self.get_related_list():
opts = rel.related_model._meta
label = opts.app_label
model_name = opts.model_name
field = rel.field
rel_name = rel.get_related_field().name
verbose_name = force_text(opts.verbose_name)
lookup_name = '%s__%s__exact' % (field.name, rel_name)
link = ''.join(('