This is also the story of how I switched from using pure PHP to Flask and then to Django.
When I started out in web development, I had a vague sense that web applications needed a programming language, a database and a web server to function. That was 3 years ago. When I found PHP, it was great! For the first time, I could write web apps that could actually work! I largely followed the book PHP and MySQL for Dynamic Web Sites by Larry Ullman (It's a great book. Full of best practices, and I learned SQL from it, but I later moved away). Because it was my first time, I had no way of comparing the methods used in PHP with any other language or framework. Validation and file uploads were done manually and database queries were done using raw SQL (don't forget about the potential for SQL injection...). That seemed like the normal way the world worked.
Luckily, at the time, I was finishing up on learning intermediate Python. At the time, it seemed like great idea to explore alternative ways of programming web applications. I found Flask and Django and explored both. Flask was easier to learn and to actually write apps at first because it is so lightweight. Admittedly, Django was difficult because it seemed all like magic. In the beginning, I often had situations where something was easy to accomplish in Flask, and I needed to get help to find out how to do the same thing in Django. The result is that I wavered between Flask and Django for nearly a year, to the point of writing the same apps in both frameworks. Looking back, doing these "time wasting" exercises have really informed my opinion on what I think is most suitable for long term production use.
I favoured Flask over Django at first until I had to do real things in order to get my applications into production. At that point I felt that Django could just work out of the box while with Flask, I had to integrate all the functionalities I wanted. Lots more dependencies to deal with. For example, to add sitemaps, I would have to add another package, and to add database migrations, I had to add another package. The worst thing about this was that these packages may have different release schedules or may have long term support problems. Another major advantage of Django was the significantly larger community on Stack Overflow and the availability of books to read (though not all are up to date). Looking to avoid all the long-term problems, I finally decided to concentrate on Django and pretend that Flask did not exist (other wise I would have been tempted to switch back and forth, getting nothing done at all. Even worse that having no framework).
The first thing I was impressed with the Python frameworks was how easy it was to build clean and beautiful URLs. No longer I need to make all pages end with meaningless (at least to the general user) extensions such as ".php" or ".html", because the URLs do not really have to correspond to the file structure. No longer I had to worry very much about making a fatal server configuration mistake and accidentally expose all of my codebase and database access information. Even better, I learned a whole new concept that encourages one to keep code structured and organized, separating the logic from the display and design. The code then became much much easier to think about and reason. I was so amazed and impressed by this whole abstraction that I actually went and read the source code of the Django URL dispatcher to see how they implemented it.
Since I had decided to go with Django, I tried to get as many books as i could on that subject. Something caught my eye. It was Test-Driven Development with Python by Harry Percival. That really changed things for me. I started using tools like git and learned how to put a Django application into production. I could see that it was perfectly possible to continuously build on existing complex systems without worrying here and there about how your new idea/feature will impact the rest of the system. A failed test will tell you that. There is little need in worrying about every little thing and obsessively memorize what each part of the codebase does. I was sold on test-driven development. Seeing that Django had good support of such practice, and that PHP did not have any, I started having doubts about putting a PHP app into production.
I decided to abandon PHP around that time. It felt too "hacky" at that point, and felt that it required flimsy configuration for it to work reliably. At that time, I was not aware of PHP frameworks (for example, Laravel), so I did not even bother to give it another chance. But before truly leaving it though, I wrote a URL dispatcher a la Django in PHP. I was so amazed that code can be used to build such eminently useful abstractions that I had a strong desire to try to implement those Django abstractions in PHP as an academic exercise. I separated the database access and query functions from the main processing and from the html templates. That was very different from how I would have done it just a few months ago when everything was put into a template with little code reuse. It was goodbye to PHP after that. After this circuitous adventure, I realized that abstractions can really be wonderful as they enable us to build up very complex systems (with all the unit and functional tests of course!).