How Django helped me launch MVP faster

Krishna G. Lodha
The Startup
Published in
6 min readJun 5, 2023

I recently launched beta version of my product https://writingpad.io/ as MVP. This app is made for anyone who does lot of Copy ➡️ Edit ➡️ Paste during their work. I personally felt the need of this app as in my day to day job of developer, I need a scribble pad to write text, API calls, make changes to it and try on browser. I hate running desktop apps as they occupy RAM while running, and also I felt issue with Apps like Notion , Evernote etc. because they are quite big and contains lot of features. It might become difficult to use them without signing in.

I was not sure if It is just me or people also needed something like this. I talked with people on LinkedIn, Twitter and reached out to folks on WhatsApp. People suggested lot of cool options like Apple notes, Obsidian, google keep, etc. But again I wanted something quick and fast to run and does the job without logging in.

I decided that probably I’ll build something quickly and launch. But as of 2023, there are few things that a website must have even in MVP.

  1. Responsive web Interface
  2. Backend to store Notes
  3. Fast and Secure Web app, etc.

Being someone who has worked with python for a long time, I wanted to stick with it since it is my forte. Learning node.js or trying to make one Front end app and one Back end app will need weeks and weeks of time. Thus I decided to visit an old friend of mine…

Django — The web framework for lazy people

I’ll be walking you through bit and pieces of my application and how Django helped in each of those

🖼️ Interface

The most important feature for me was an ability to write notes. Since UI/UX and Front end is not the strongest arrow in my quiver, I wanted to stick to basics. To create a quick UI, I decided to use Bootstrap . Some might say that it’s quite old school and there are better options available, Yeah! I agree to you and probably I’ll shift to TailwindCSS soon. But as an MVP, I thought Bootstrap should be okay.

I decided to use Django templates , and this enabled me to use dynamic data from backend to UI. Django allows us to loop through data and render HTML .

e.g. When user saves notes and visits the homepage, we want to show their saved notes as list which then user can click on it.

I was able to do that quickly by loading users notes in views.py (more about it later) , and then load data on template as follows

<div class="flex-grow-1 position-relative">
<div class="d-flex flex-column position-absolute top-0 start-0 bottom-0 end-0 overflow-auto" >
{% for notes in myNotes %}
<div class="savedItem">
<a href="{% url 'notes' id=notes.id %}" class="btn btn-sm btn-dark text-start d-flex justify-content-between align-items-center" aria-current="page">
{{ notes.chat_text|truncatechars:15 }}
</a>
</div>
{% endfor %}
</div>
</div>

By writing for loop, I was able avoid writing loop in JS and creating components.

I had planned for two pages of notes, one to write note, and one to view and edit existing written note. Most of the components I planned in it were same and thus I decided to use Django base template extension mechanism. This allowed me to create one base template and then create blocks inside it which then can be used in another templates to extend the base.

I started with creating base template file as base.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %} Writingpad.io {% endblock title %} </title>
</head>
...

by using this, now the Title of my page has became dynamic, which means If I create another file note.html

{% extends 'main/base.html' %} 

{% block title %}Single note - Writingpad.io{% endblock title %}

As you can see, in the note.html file, I don’t need to rewrite the entire HTML again, but simply extend the base.html and fill in the blocks

🔐 Authentication

Even though you can access the functionality of creating notes without logging in, you can create account to save notes. I wanted to be sure that people don’t get scared of signing up, thus I decided to use use Django’s Internal Authentication system. Django allows users to create account with simply username and password. This way users don’t have to worry about sharing personal data.

Django has UserCreationForm as a ready made user registration form. I simply initiated the empty form and checked it after POST request is made in function

from django.contrib.auth.forms import UserCreationForm

def register(request):
# signup form
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect("login")
else :
form = UserCreationForm()
context = {
"form": form,
}
return render(request, "registration/register.html", context)

and then I rendered the form on UI by looping the form

<form method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger">
{{ form.errors }}
</div>
{% endif %}
{{ form.as_p }}
<div class="d-flex align-items-center">
<button type="submit" class='btn btn-success'>Signup </button>
</div>
</form>

I was also able to render the errors by simply referring to form.errors.

Apart from registration, Django also has other authentication mechanism in built , and can be accessed by simply adding

urlpatterns = [
...
path("auth/signup", register, name="signup"),
path("auth/", include("django.contrib.auth.urls")), # Add default auth
...
]

by doing this I was able to add

  • Login
  • Logout
  • Password Change, etc. directly

🔑 Authorisation

Once users are created, it is also equally important to plan out how authentication and authorisation will work. How can we confirm whether someone trying to access a note is in fact the owner of the note.

Django makes it easier than tying shoe lace 👟

While create Django view, we can leverage in built user method to access current user and filter database accordingly, We can also put it in conditional statement to check if any user is even logged in or not.

def index(request):
if request.user.is_authenticated: # check if user is logged in
notes = Note.objects.filter(user=request.user).order_by("-id") # filters notes owned by user
else:
notes = Note.objects.none() # returns nothing if user is not logged in

By doing this I always get/or don’t get the notes according to logged in user.

💼 Admin Panel

If there is one thing that I love most about Django, is its internal Admin Panel.

Django comes with by default superuser flag which helps in declaring whether the user is admin or not.

Django provides in built admin panel where I am able to access user details (of course the password is encrypted ) , but I can also access things such as last login, notes, etc. This enabled me to understand the user behaviour better.

Another good part about Admin panel is I’m able to add things such as list of upcoming features, change users from normal to Admin or assign them abilities to be part of certain groups, etc. without adding single line of extra code.

And just like that, I was able to create https://writingpad.io/ within a week. I have many features planned to integrate in the application as you can see here https://writingpad.io/project , and as I keep adding it, I’ll also keep on sharing the Django way of how I done it.

--

--