Learning Django – Beginner Mistakes I Made That You Can Avoid

I am a newbie to Django web framework. I am not a coder by profession too. I had no help whatsoever from anyone, and everything I learnt was through trial and error. I have made countless mistakes, something which I laugh at now, when I look back. After struggling a lot trying to understand the basics, I was successfully able to create a simple website to add/update/delete contacts. It has been deployed in Heroku (free server). Whatever I have written here is purely my personal opinion. If you are a beginner and are keen on exploring the world of Django, you should go through this post. It may help you somewhere down the line.

Those of you who would like to explore my website (still needs some work), it is: [https://djangophonebook.herokuapp.com](https://djangophonebook.herokuapp.com/)

Below are the key challenges I have faced in my journey to creating my own website:

**Official Documentation Vs Tutorials** – Many people who have had experience with Django or some form of coding in general will tell you to go through the official documentation to learn more about this awesome web framework. Let us be practical. Not all of us prefer such high technical details. At first glance, any document that specifies the inner working of a framework like this one will intimidate beginners. No doubt, Django documentation is exhaustive and very well prepared, but I would recommend you going through some great video tutorials that give us some sense of all the available features and how to implement them in a real project. I personally went through Django tutorials from ‘Corey Schafer’ on YouTube. It is one of the best I have found on the internet. There are many others but I always go back to his videos. I also found the Try Django series by ‘CodingEntrepreneurs’ on YouTube to also be a very good source. Once you have some sense of direction, the official documentation makes a lot more sense.

**Django Version** – A lot of tutorials out there were created for Django 1.x versions. While it is tempting to use the same versions for our project, I highly recommend going for the latest stable version of Django. It not only eliminates rewriting code, but it also gives us access to newer features which the older versions may not have.

**Using Git and GitHub** – When I first started working on my project, I ignored using Git to maintain a version control. One day when I was clearing some old folders in my PC, I accidentally deleted my entire project folder. That is when I realized the importance of using Git to keep track of changes I am making in my project. For a newbie like me, it took a while to figure out how to use it (I still struggle with it sometimes) but it saved me a lot of headaches. I also used GitHub to dump all my code as an open source project. You should consider using Git. It will really help you if you messed up and want to revert to an older version of your project. Trust me, it is really frustrating to rewrite code all over again.

**Using .gitignore File** **–** If you are using Git, make sure you also use the gitignore file. Add all the files or folders you do not want Git to track. There is a GitHub link ([https://github.com/github/gitignore](https://github.com/github/gitignore)) for this. I refer to the python.gitignore file and simply copy-paste everything from this file to my gitignore file. I leave everything as is even though some of the details are not necessarily specific to Django. It covers everything for my use-case. I highly recommend using this as a starting point. You can then modify your file based on your requirement.

**Brush Up Your Front End Skills** **–** Yes, you will need it. You will need to know at least the absolute basics of HTML to create templates in Django. Knowing a little bit of CSS and JavaScript is even better. It can help further customize the look and feel of your website. I am a total noob when anything front end. I know just enough HTML to create a bare-bones template and very less CSS knowledge to even consider customizing my website. For people like me, thankfully, there is Bootstrap which gives us ready-made widgets that I can use in my website. It simplifies a lot of my front end requirements. My project is built purely on HTML and Bootstrap.

**Using Virtual Environment** – It is a good practice to create a separate virtual environment for your project. This will also come in handy when you are ready to deploy your project. I learnt its importance the hard way. Now, I first create a virtual environment, install all the required packages and then work on my project.

**Using Separate settings.py Files For Development & Production** – I have not come across too many tutorials explaining why it is a good idea to have separate settings.py file during development and production. Having separate files reduces clutter and makes testing your code lot more efficient. Do keep this in mind when you want to work on a large-scale project. Although I never implemented it, many experts recommend it.

**Creating Custom User Models** – Most tutorials use the inbuilt User model to store and handle user related data. What if you wanted to make the email ID or mobile number as the login ID? What if you wanted some fields of your own to collect from the user at the time of registration, like city, state, gender, etc? You can do that by creating a custom user model of your own. That is when you should consider going through AbstractUser and the AbstractBaseUser classes. I usually refer to two websites – [https://simpleisbetterthancomplex.com/](https://simpleisbetterthancomplex.com/) and [https://wsvincent.com/](https://wsvincent.com/) for implementing this. CodingEntrepreneurs on YouTube ([https://www.youtube.com/watch?v=HshbjK1vDtY](https://www.youtube.com/watch?v=HshbjK1vDtY)) also cover creating custom user models in one of their videos. I would highly recommend watching it to get an idea of how things really work instead of just copy-pasting code.

**Using Social logins** – Most websites today give us an option to login or sign up using one of the various social logins like Login with Google, Login with Facebook, etc. In my personal experience, majority of the users who explored my website used the social login option I provided instead of the standard sign up procedure. It makes a lot of sense to implement this in your project before you take it live. ‘Django-Allauth’ library is a very good start, that I used to implement google sign ins.

**Designing your Models** – It is always a good idea to think through what kind of data you would like stored in your database before you can deploy your project. Which fields should be mandatory, which fields can be optional, what information you want to capture at the time of user signup, all these have to be thought through well in advance. Making any changes to the models once a website is taken live can prove to be a very costly affair as I  have made that mistake.

**Function Based Views Vs Class Based Views** – This is always going to be a dilemma for beginners like us. In my experience, I found generic Class based views much, much easier to write, takes a lot fewer lines of code, and makes things look neater on paper. This is where we can really see all the magic happening, as Django does all the heavy lifting for us in the back end. However, I also found out that implementing any custom logic using a CBV is not very user friendly. I could not find much material on the internet too on how to use and override the existing methods of a CBV. That is exactly where the Function Based Views thrive. They make take a lot more lines of code to write, can be more complex to interpret, but they can be powerful when we have to implement any custom logic. Understanding how both CBVs and FBVs work really helps. But for most use-cases, CBVs get the job done without breaking a sweat. And that’s the preferred path I take when creating my views

**Routing and URLs** – In addition to planning your models, it also makes sense to plan all your routing at the time of creating your project. Having a clear idea of the various URLs can simplify writing their corresponding views too. I always make it a point to keep urls consistent across apps and ready for CRUD operations. It makes things easier when writing REST API endpoints too.

**Handling Static and Media files in Production** – Not many tutorials will tell you some of the challenges we will face when we try to deploy our project. I tried deploying mine on Heroku. Serving static and media files is not supported by Django by default when you set DEBUG = False. For static files, WhiteNoise library did the job for me. Its documentation is also straightforward. Heroku does not store media files. We have to use some other service like Amazon’s S3 and update the settings.py file accordingly with all the required parameters. S3 can also be used to serve static files but the major drawback is, it is not free. As a result , my website currently cannot load any profile pictures selected by users. I am yet to find an alternative to it. Plan how you want to serve your media files in advance. Take into consideration the cost involved.

**Handling Permissions For Different Users** – This is an important point to consider. One of the challenges I had was figuring out how to grant or restrict access to a specific URL for different users. For example, User A may have read only access to a URL while User B may have write access to the same URL based on certain conditions. You do not want one user to access another users profile and update it. That is where you need to ensure proper permissions are granted to the URLs being accessed. Corey Schafer’s tutorial covers this really well.

**Creating Custom Middlewares** – Not many tutorials cover this topic. I am yet to figure out how to create a Middleware of my own. When I have more information, I will update this section.

**Improving Security Of Website** – I have not come across too many tutorials that explain *‘python manage.py check –deploy’* and why its important to ensure we have necessary security in place before a website is taken live. Something you should explore before taking your website live. Security of your website and security of your user's data has to be taken seriously.

**Protecting Your Admin Interface** – One of the reasons I love Django is because it comes with a lot of security features built in. One such feature is the fully functional Admin interface. Once a user gets access to the admin page, he/she can really misuse the data. When creating your superuser, make sure you do not use common names like 'admin' or 'manager' as the login ID. Also make sure you use a very strong password that's hard to guess. Also, change the path of the admin page to a completely different and hard to determine name. Avoid using the default 'admin/' path. I also came across a 3rd party library named 'django-admin-honeypot' that spoofs unauthorized users by creating an admin like page but does not do anything else. It additionally also captures the details of these users like their IP address, and other parameters in a table which can be accessed in the real Admin interface. You can then decide if you want to block them from accessing your website or take necessary action. I highly recommend using django-admin-honeypot as an extra layer of security for your admin interface.

**Protecting Secret Key and Other Critical Data** – One of the challenges of making your project as open source is to protect the SECRET KEY and other personal values like email IDs and passwords that you do not want the rest of the world to see. I followed the suggestions provided by Corey Schafer in his YouTube video and saved all such important values as environment variables. In case you feel like your SECRET KEY knowingly or unknowingly got exposed, it has to be changed immediately. You can use the secrets module that comes with python (requires Python 3.6+) to generate a strong secret key. Again, Corey Schafer's tutorial covers this part too.

**Making Responsive Websites** – Not many tutorials emphasize on making a website both desktop and mobile friendly. When I first created my website, it was rendering fine on my PC but when I tried accessing it on my mobile, I realized I had to redo some of my templates. Taking this into consideration right at the time of creating your templates is going to save you a lot of rework later on. I mostly used Bootstrap as the front end, which emphasizes on creating mobile-first projects.

**Writing Tests** – There is a tests.py file that’s created for every app. I still have no clue how to write tests. I have observed that a lot of packages or libraries that are available for Python or Django on GitHub do have a lot of tests. Again, not many tutorials explain how to write tests. This is something I am still trying to figure out. When I have more information, I will update this section.

**Using REST APIs** – While REST APIs are more of a separate topic in itself, beginners like us should be aware of why its important to plan for it, how to create APIs, and how to integrate it with other front ends like Angular or React. In my experience, writing a REST API side by side when designing the views really makes things more efficient and saves a lot of hassle trying to figure out permissions and other aspects. ‘Django Rest Framework’ is the preferred library for REST APIs. I usually create a separate app with name ‘api’ and write all my serlializers and views for other apps here. It keeps everything in once place. Although my project has API endpoints, I still have to create some the APIs.

**Setting DEBUG=False Before Deployment** – Leaving DEBUG=True during deployment is common mistake which even I made. Before taking your website live, do not forget to set DEBUG value to False in the [settings.py](https://settings.py) file. You do not want the end user to see all the exceptions and other coding related information whenever a url throws an error. Corey Schafer explains really well how this can be handled in his tutorial.

**Deploying The Project** – This is another real headache for first timers like me. Where Should I deploy my project (Heroku, PythonAnywhere, DigitalOcean, AWS, etc)? What all preparations should I do? Which database do I use in production? What all files do I need to have to start the deployment (like requirements.txt, procfile etc)? Should I go for free server or a paid one? A lot of things to consider. I deployed mine on a free Heroku server by going through Corey Schafer’s video on YouTube.

16 thoughts on “Learning Django – Beginner Mistakes I Made That You Can Avoid”

  1. This is great! I am just starting off and I already complete half of your great suggestions. The primary topic that I am struggling with right now is “Designing Your Models”. Any help or direction of where I could learn more would be much appreciated.

  2. Thanks for sharing your thoughts and experiences! I think this will help a lot of people starting out on their Django journey.

    If you want to learn more about testing with Django, I would recommend [https://www.obeythetestinggoat.com/](https://www.obeythetestinggoat.com/). It walks the reader from a new project to deployment with Django by following the TDD (Test Driven Development) methodology. Judging from your write up, many of the topics he covers will be review; but, he really drives home testing with functional and unit tests. Have fun!

  3. Very nice and tidy write up. I’m going through all the phases you described above. No help no idea what the f*** I’m doing. However the website is coming together mint.

  4. Also for complex models prototyping you can use MySQL workbench. It’s really helps to not get lost at planning stage.

  5. If I can upvote this 1000x time I would do it happily, most of these points I had faced during my learning path with django and the remaining one still working on these to learn.

    CBV was the one I didn’t even know about until I was hit by a random interview challenge which is only about using CBV to crack it.

    **Custom user insetad of using built-in user is the thing you should always always always do**, the project I inherited at my job was using the built-in and you can’t extend it so I had to make some tewaks to switch using a custome one and persist user data, requirment always change so don’t tie yourself.

  6. **Designing your Models** \- another thing people should think about when designing their models is how they are going to access the data. There are cases where joins make sense, there are cases where some very simple data (eg. flags or KV things) can be stored inside the model instance, etc.

    **Function Based Views Vs Class Based Views** \- As you said, it’s a little awkward to overwrite certain methods of the CBVs because it’s not always straight forward what methods are available and what are not where, and what side effects are going to be. It comes easier with experience and with more OOP design experience. In the long run, you will be more productive using class based views, but it’s a rather steep learning curve until you get the hang of it.

    **Making Responsive Websites** \- I think this is more CSS/HTML/UI/Frontend related rather than django specific. Django doesn’t dictate nor care about how you structure and style the templates. But yes, it is a very important topic to keep in mind in today’s industry

    **Writing Tests** \- I use [pytest-django](https://pytest-django.readthedocs.io/en/latest/) and I totally recommend it.

    **Deploying The Project** \- Usually it is the same deploying flow with every python based web app. The application itself is served as a WSGI application that you then serve through a specialized webserver that supports WSGI (I prefer gunicorn or uwsgi). And the deployment and management of auxiliary resources such as database, redis, search index, etc kind of fall outside django’s scope. This is to be figured out by the users on their own. But I agree, that people usually jump the django bandwagon because it is being promoted as a all-batteries included web framework and the deployment aspect and understanding how all its moving parts play together could be better explained and focused on.

  7. Good post. I had a few thoughts.

    > Official Documentation Vs Tutorials

    I just wanted to say that the official documentation includes a tutorial. It’s easy to follow, comprehensive, and guaranteed up to date. I’d definitely recommend working through that one, at least as far as testing.

    After that, if you find video easier to learn from, then by all means check out some videos.

    > Django Version

    I’ve been doing Django about a year, and I started with 1.11. Just recently Python 2 hit end-of-life, so I upgraded to Django 2. I very deliberately didn’t go to Django 3 because I didn’t need the feature set, and because I don’t like using bleeding edge

    I guess what I’m saying is don’t necessarily rush to use the latest and greatest. Django is well tested, but bugs do happen and it can be a while between releases.

    > Using Git and GitHub

    Needn’t be Github, but for pete’s sake, do use some sort of version control.

    > Brush Up Your Front End Skills

    Learn a bit of jquery as well. You get it anyway with bootstrap, and it makes a lot of things a lot simpler. AJAX calls in particular.

    > Using Virtual Environment

    I didn’t do this until the Python 3 upgrade more or less forced the issue. It definitely makes life easier.

    > Creating Custom User Models

    I took the view that the default Django user model was robust and had been tested by thousands of sites world wide. I figured, lacking a compelling reason to change, I’d stick with that. It seems to have worked.

    > Designing your Models

    Yeah, a bit of database theory is very helpful.

    > Function Based Views Vs Class Based Views

    I went with functions from the start. They’re easy to write and you can do anything fairly intuitively. That said, if you’re using a lot of forms, separating GET and POST queries is a lot simpler with class based views.

    Bottom line I guess is start with whichever one you’re most comfortable, but be prepared to use the other when called for by the situation.

    > Routing and URLs

    Yeah. Most of my urls follow the format of


    With the views being named


    > Protecting Your Admin Interface

    One thing I did was to disable the database access from the admin page entirely. I can still do database level stuff from the Django shell or from the underlying database Reply

  8. Saved! Thank you for taking the time to put this together. It certainly helps someone like me. Just wondering, how long did it take for you to achieve some level of proficiency with django?

    I ask because I’m a newbie to coding and have been struggling quite a bit. I’m doing code alongs, but seem to be forgetting even the basics.

    Again, thank you.

  9. Reading your post makes me feel that I am going in the right direction. I also follow Corey Schafer’s tutorials and made https://django-discussion-blog.herokuapp.com/ which is my first project in Django :). Glad to share with you! Few problems I am still facing are: 1) I am not confident in using the python shell for exploring my project and writing test cases

  10. Thank you everyone for all the love and support for this post. When I wrote it, I never imagined so many people would be influenced by it. Thanks again!


Leave a Comment