0

In some of my blog posts using django and markdown2, I am trying to include a form as follows:

views.py:

def post_detail(request, slug=None):
    instance = get_object_or_404(Post, slug=slug)
    if not instance.published:
        raise Http404
    return render(request, "posts/post_detail.html", {'instance': instance})

My template post_detail.html contains a {{ instance.get_markdown }} variable:

{% extends "base.html" %}
{% block body_content %}
<div>
     {{ instance.get_markdown }}
</div>
{% endblock body_content %}

base.html:

<html>
<body>
{% block body_content %}
{% endblock body_content %}
</body>
</html>

models.py:

import markdown2

class Post(models.Model):
     ...
     text = models.TextField(verbose_name=_("Text"))
     ...

     def get_markdown(self):
         return mark_safe(markdown2.markdown(self.text)) 

Example for a saved text in Post:

### Example

<form method = "POST">
{% csrf_token %}
First name:<input type="text" name="firstname">
<input type="submit" value="Submit">
</form>

This way, the page simply shows the string "{% csrf_token %}" within the form. How can I render the post with csrf protection?

My temporary solution is:

post_detail.html:

{% extends "base.html" %}
{% block body_content %}
<div>
     {{ instance.get_markdown_text }}
</div>
{% if instance.form %}
<div>
    <form method = "POST">{% csrf_token %}
        {{ instance.get_markdown_form }}
    </form>
</div>
{% endif %}
{% endblock body_content %}

models.py:

import markdown2

class Post(models.Model):
     ...
     text = models.TextField(verbose_name=_("Text"))
     form = models.TextField(verbose_name=_("Form"), blank=True, null=True)
     ...

     def get_markdown_text(self):
         return mark_safe(markdown2.markdown(self.text))

     def get_markdown_form(self):
         return mark_safe(markdown2.markdown(self.form))

I'm not very happy with this solution, because of the unnecessary field "form" and method get_markdown_form in Post and post_detail.html.

tweili
  • 1
  • 1
  • does your template extends some base.html or any other html? – Carmine Tambascia Dec 13 '17 at 11:42
  • you need to put correct html tag for parameters like First name etc like the example here https://docs.djangoproject.com/en/1.11/topics/forms/ – Carmine Tambascia Dec 13 '17 at 11:49
  • yes, template extends base.html and html tags are correct. If I put the example-form directly in post_detail.html, the csrf_token/csrf protection works just fine. Is it maybe because of mark_safe()? – tweili Dec 13 '17 at 12:09
  • can you put all the template you are refer on?Also the base.html. I believe /could be you are not inheriting the blocks from the base.html, have a look to this https://stackoverflow.com/questions/1900892/nested-blocks-in-django-templates – Carmine Tambascia Dec 13 '17 at 13:15
  • Unfortunately, the problem is somewhere else; for full template, see edited post. – tweili Dec 13 '17 at 16:30
  • hm, would it not be easier to save your `Example` as a html file (use FileFiled in the model) and [include](https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-include) it in `post_detail.html`? The problem in the way you do it now is that `{{ instance.get_markdown }}` would need to be evaluated twice, 1. replace it with the example content. 2. evaluate the python tags in the example content. this is unfortunately not going to work! – j-i-l Dec 13 '17 at 16:36
  • I suspected that this is not going to work. Maybe I stick with my temporaly solution, an extra html file for each form is currently not an option for me. Nevertheless, thanks for your answer! – tweili Dec 13 '17 at 17:13
  • @tweili I don't understand if you found a solution, but the part you added after "My temporary solution is" should work, the code before as said is missing many information. – Carmine Tambascia Dec 13 '17 at 22:43

0 Answers0