Search code examples
pythonhtmldjangofilemarkdown

Extra blank lines in markdown file after submitting and saving in Django


I have a problem with saving information submitted by the user. One of my website's pages should have a textarea for markdown text. Data entered by the user in this area should be saved in a separate file after submitting. But when I open saved file after submitting, there are extra blank lines. Functions from views.py and HTML form are presented below.

from django.shortcuts import render
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage


def index(request):
    if request.method == "POST":
        save_data(request.POST.get("title"), request.POST.get("content"))   
    return render(request, "my_app/page.html")


def save_data(title, content):
    filename = f"files/{title}.md"
    if default_storage.exists(filename):
        default_storage.delete(filename)
    default_storage.save(filename, ContentFile(content))
<form method="post">
    {% csrf_token %}
    <label for="title">Enter a title:</label><br>
    <input id="title" type="text" name="title">
    <br><br><label for="textarea">Enter the information:</label><br>
    <textarea id="textarea" name="content"></textarea><br><br>
    <input type="submit" value="Save Page">
</form>

If I try, for example, to type in the textarea the following text:

# My file

This is markdown file.
This file was created as an example for my question.

I see this after submitting:

# My file



This is markdown file.

This file was created as an example for my question.

Could you help me solve this problem, please? Thank you in advance!


Problem solution:

OK, the essence of the problem becomes clear if you try to use print(repr(request.POST['content'])). After execution this command you will get # My file\r\n\r\nThis is markdown file.\r\nThis file was created as an example for my question.. So, the problem is the difference in new line encoding in Windows and Linux/Mac OS. Read more in the answer below.


Solution

  • This looks to me like a difference in how new lines are encoded. Indeed, Windows uses a carriage return (\r[wiki] and then a line feed (\n[wiki], whereas Linux and Mac OS X use a line feed (\n) only. Now often certain systems will then also interpret this as a new line. But this is rendering, not the content. Likely the editor in which you look at the file has set the line endings on \n or LF or Linux.

    You can however clean the input before saving it with:

    def index(request):
        if 'title' in request.POST and 'content' in request.POST:
            save_data(
                request.POST['title'], request.POST['content'].replace('\r\n', '\n')
            )
        return render(request, "my_app/page.html")

    Note: Please use request.POST['content'] over request.POST.get('content'). Using .get(…) often only silences the error, but not the problem: indeed it will work if the key is missing. But if the value for that key is really required, it will only result in more trouble later in the process.