RailsTweeter
RailsTweeter

Reputation: 1635

Pass other object/data into Flask Admin model view edit template

I'm extending the edit template for a ModelView so that I can show some other information from the database that is relevant for determining how to edit the record in this view. I know how to extend the template and get it to work, but I can't figure out how to query an object and use it in the template.

Also I need to use the value from the model/record in querying the new object I need to pass.

Here is my code from init.py:

class MilestoneView(ModelView):
    edit_template = '/admin/milestone_model/milestone_edit.html'
    can_delete = True

    #i need something like this to work:
    referrals = Referral.query.filter_by(email=model.email)
    #then i need to pass referrals into the template

admin = Admin(app, name="My App", template_mode='bootstrap3')
admin.add_view(MilestoneView(Milestone, db.session, name='Milestones'))

Then from milestone_edit.html, I want something like this to work:

{% extends 'admin/model/edit.html' %}

{% block body %}

    {{ super() }}

    {% for r in referrals %}

        <p>{{ r.name }}</p>

    {% endif %}

{% endblock %}

But of course the referrals object is not available to use in the template. How do I customize this ModelView in order to pass this object in from the init file? I've reviewed the available posts on this subject(ish) on here and haven't found an answer. Thanks in advance.

Upvotes: 0

Views: 1040

Answers (1)

pjcunningham
pjcunningham

Reputation: 8046

Override your view's render method, see code on Github, and test if the view being rendered is the edit view. Now you can inject any data into the kwargs parameter. For example:

class MilestoneView(ModelView):

    def render(self, template, **kwargs):

        # we are only interested in the edit page
        if template == 'admin/model/milestone_edit.html':

            # Get the model, this is just the first few lines of edit_view method
             return_url = get_redirect_target() or self.get_url('.index_view')

            if not self.can_edit:
                return redirect(return_url)

            id = get_mdict_item_or_list(request.args, 'id')
            if id is None:
                return redirect(return_url)

            model = self.get_one(id)

            if model is None:
                flash(gettext('Record does not exist.'), 'error')
                return redirect(return_url)

            referrals = Referral.query.filter_by(email=model.email)
            kwargs['referrals'] = referrals

        return super(MilestoneView, self).render(template, **kwargs)

Note how the model is retrieved. This is a direct copy of the code in method edit_view code. Adjust the code for your use-case.

Use the variable referrals in your edit Jinja2 template.

The render method is called in the following routes for each view:

'/' - i.e. the list view code

'/new/' - code

'/edit/' - code

'/details/' - code

Upvotes: 1

Related Questions