After working out a project, it might require too much tweaks and changes to get it working right...
What can I do to prevent this?
There is simple rule, that I apply all the time because I tend to be a perfectionist too. And perfectionism leads you to mediocrity.
To prevent your software from having an unfishined state of missing feature that will make it unusable, use this definition of done for each feature you produce. Don't start the next feature until ALL steps are completed:
I assume you can create a release with one mouse click (using build scripts)
What's "too much" tweaks and changes? Software maintenance can take far more time than the initial development of the software. There's nothing wrong with that. To keep organized, use an issue tracker.
Regardless, you'll of course want to initially make it as good as you can. For that, nothing beats testing.
Before I give my answer (or suggestion of an answer, really), I must say that I don't have very much experience of large projects and will only state what I've read and believe to be one of the causes. I may very well be wrong, but then I will most likely have learned something from all the comments I'll receive. ^^
One important factor, I believe, is not to let your code deteriorate as the project is under way. This can be prevented in many ways, of which I only know a few:
Don't wait too long with refactoring: Refactoring does take some time, but it'll be worth not having to do convoluted function calls just because you couldn't be bothered rewriting the code to allow for that extra parameter. More intuitive and less duplicated code reduces the number of bugs.
Fix the broken window: In The Pragmatic Programmer, I read of a phenomenon known as the broken window. The authors argue that code will begin to deteriorate in the same way as a building deteriorates: it starts with a broken window. In code, this means ugly fixes, naming of variables, functions; in general just bad code. I have found this to hold true: I code better and am more happy about coding when my code foundation is solid. If there are too many broken windows, I often don't feel like making the effort to write good code. So if you see a broken window, fix it as fast as possible; refactor if you have to. This will lead to fewer bugs and unnecessary tweaks.
And don't forget to read Pierre 303's answer.