Search code examples
pythonflaskflask-admin

Adding Contact Page to Flask Admin


I have a Flask-Admin project I am working on and am looking to add a contact us page. I am following the example on https://code.tutsplus.com/tutorials/intro-to-flask-adding-a-contact-page--net-28982

This issue is that it is designed for Flask but all my templates are based on the Flask-Admin template.

@app.route('/contact', methods=['GET', 'POST'])
def contact():
  form = ContactForm()

  if request.method == 'POST':
    if form.validate() == False:
      flash('All fields are required.')
      return render_template('contact.html', form=form)
    else:
      msg = Message(form.subject.data, sender='contact@example.com',     
          recipients=['email@email.com'])
      msg.body = """
      From: %s <%s>
      %s
      """ % (form.name.data, form.email.data, form.message.data)
      mail.send(msg)

      return render_template('contact.html', success=True)

  elif request.method == 'GET':
    return render_template('contact.html', form=form, admin=admin)

The contact.html extends two admin templates

{% import 'admin/layout.html' as layout with context -%}
{% extends 'admin/base.html' %}

as a result there is an error message thrown.

jinja2.exceptions.UndefinedError: 'admin_view' is undefined

I know I can amend the template to remove the extending the admin templates however the navigation for the whole site is done by

{{ layout.menu() }}
{{ layout.menu_links() }}

so ideally I would like to get the contact us page working with the admin template. I'm sure not sure how to pass the whole admin context across.


Solution

  • You need to use flask_admin.base.BaseView.render method to process your templates with flask-admin context. It may look like this:

    from flask_admin import BaseView, expose
    
    class ContactsView(BaseView):
        @expose('/')
        def index(self):
            # Here are the contents of your "contact" route function
            return self.render('contact.html', form=form, admin=admin)
    

    You can activate this view the same way as ModelView instances:

    admin.add_view(ContactsView('Contacts', url='/contacts'))