2017-09-13 2 views

Répondre

3

Il n'est pas clair sur la capture d'écran si vous utilisez modeladmin ou snippet s pour exposer ce modèle à l'utilisateur, mais je suppose que le premier.

Je ne connais pas un hook qui vous permet d'ajouter des boutons directement à l'en-tête, mais le modèle uses blocks qui devrait nous permettre d'écraser juste cette partie.

Nous pouvons tirer parti des resolution order des modèles et créer /modeladmin/app-name/model-name/index.html qui aura la priorité sur /modeladmin/index.html. Alors, étant donné votre application appelée feedler et un modèle appelé Entry, créez /modeladmin/feedler/entry/index.html avec le contenu suivant:

{% extends "modeladmin/index.html %} 

{% block header_extra %} 
    <a href="#">My New Button</a> 
    {{ block.super }}{% comment %}Display the original buttons {% endcomment %} 
{% endblock %} 

En ce moment, le bouton ne fait pas beaucoup. Pour créer une action qui interagira avec l'administrateur de ce modèle, vous devrez créer un bouton/url/permission helpers et une vue.

Supposons que l'action exporte les objets dans un fichier CSV. Préparez-vous, il y a pas mal de code à venir.

En /feedler/admin.py, créez le bouton/url/aides et autorisation d'affichage:

from django.contrib.auth.decorators import login_required 
from django.core.urlresolvers import reverse 
from django.utils.decorators import method_decorator 
from django.utils.functional import cached_property 
from django.utils.translation import ugettext as _ 
from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper 
from wagtail.contrib.modeladmin.views import IndexView 


class ExportButtonHelper(ButtonHelper): 
    """ 
    This helper constructs all the necessary attributes to create a button. 

    There is a lot of boilerplate just for the classnames to be right :(
    """ 

    export_button_classnames = ['icon', 'icon-download'] 

    def export_button(self, classnames_add=None, classnames_exclude=None): 
     if classnames_add is None: 
      classnames_add = [] 
     if classnames_exclude is None: 
      classnames_exclude = [] 

     classnames = self.export_button_classnames + classnames_add 
     cn = self.finalise_classname(classnames, classnames_exclude) 
     text = _('Export {}'.format(self.verbose_name_plural.title())) 

     return { 
      'url': self.url_helper.get_action_url('export', query_params=self.request.GET), 
      'label': text, 
      'classname': cn, 
      'title': text, 
     } 


class ExportAdminURLHelper(FilterableAdminURLHelper): 
    """ 
    This helper constructs the different urls. 

    This is mostly just to overwrite the default behaviour 
    which consider any action other than 'create', 'choose_parent' and 'index' 
    as `object specific` and will try to add the object PK to the url 
    which is not what we want for the `export` option. 

    In addition, it appends the filters to the action. 
    """ 

    non_object_specific_actions = ('create', 'choose_parent', 'index', 'export') 

    def get_action_url(self, action, *args, **kwargs): 
     query_params = kwargs.pop('query_params', None) 

     url_name = self.get_action_url_name(action) 
     if action in self.non_object_specific_actions: 
      url = reverse(url_name) 
     else: 
      url = reverse(url_name, args=args, kwargs=kwargs) 

     if query_params: 
      url += '?{params}'.format(params=query_params.urlencode()) 

     return url 

    def get_action_url_pattern(self, action): 
     if action in self.non_object_specific_actions: 
      return self._get_action_url_pattern(action) 

     return self._get_object_specific_action_url_pattern(action) 


class ExportView(IndexView): 
    """ 
    A Class Based View which will generate 
    """ 

    def export_csv(self): 
     data = self.queryset.all() 
     response = ... 
     return response 


    @method_decorator(login_required) 
    def dispatch(self, request, *args, **kwargs): 
     super().dispatch(request, *args, **kwargs) 
     return self.export_csv() 


class ExportModelAdminMixin(object): 
    """ 
    A mixin to add to your model admin which hooks the different helpers, the view 
    and register the new urls. 
    """ 

    button_helper_class = ExportButtonHelper 
    url_helper_class = ExportAdminURLHelper 

    export_view_class = ExportView 

    def get_admin_urls_for_registration(self): 
     urls = super().get_admin_urls_for_registration() 
     urls += (
      url(
       self.url_helper.get_action_url_pattern('export'), 
       self.export_view, 
       name=self.url_helper.get_action_url_name('export') 
      ), 
     ) 

     return urls 

    def export_view(self, request): 
     kwargs = {'model_admin': self} 
     view_class = self.export_view_class 
     return view_class.as_view(**kwargs)(request) 

En /feedler/wagtail_hooks.py, créer et register le ModelAdmin:

from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register 

from .admin import ExportModelAdminMixin 
from .models import Entry 

class EntryModelAdmin(ExportModelAdminMixin, ModelAdmin): 
    model = Entry 
    # ... 

modeladmin_register(EntryModelAdmin) 

Avec tout ce que l'installation, vous devriez être en mesure pour utiliser {% include 'modeladmin/includes/button.html' with button=view.button_helper.export_button %} dans le modèle créé ci-dessus.

+0

Merci beaucoup pour votre explication. J'ai tout fait selon vos instructions, mais malheureusement le bouton n'apparaît pas. J'espère que je ne me suis trompé nulle part. Dans votre code, cette ligne manquait: 'depuis django.utils.decorators import method_decorator'. Voici mon modèle **: ** [github repo] (https://github.com/khashashin/public-health-ch/blob/fd2ccf68eb488365a97d6fc49d0e1c8d6f4a5b49/feedler/models/models.py#L57) ** modèle: * * [modèle] (https://github.com/khashashin/public-health-ch/blob/fd2ccf68eb488365a97d6fc49d0e1c8d6f4a5b49/modeladmin/feedler/entry/index.html#L1) – khashashin

+0

Merci d'avoir signalé l'importation manquante. J'ai mis à jour la réponse. Quant au bouton maintenant affiché, je pense que c'est parce que vous n'enregistrez pas le nouveau [ModelAdmin] (https://github.com/khashashin/public-health-ch/blob/fd2ccf68eb488365a97d6fc49d0e1c8d6f4a5b49/feedler/models/models.py#L166) mais enregistrez toujours le [ancien] (https://github.com/khashashin/public-health-ch/blob/fd2ccf68eb488365a97d6fc49d0e1c8d6f4a5b49/feedler/wagtail_hooks.py#L8). Mettez à jour 'EntryModelAdmin' dans' wagtail_hooks.py' et faites-le hériter de 'ExportModelAdminMixin'. –

+0

En outre, vous pouvez probablement déplacer toute la logique d'administration du modèle vers 'wagtail_hooks.py' ou' admin.py'. Je mettrai à jour la réponse pour montrer la hiérarchie (et mettre à jour le nom de votre modèle). –