1) First, I want to state that you need to understand that Django was designed to help build simple, common use case web apps. Database skins, as someone put it. The ORM is very easy to use, although it is not well prepared for some things.
It also has a very nice advantage, which is being compatible with many RDBMS so you can have postgresql on the production server and sqlite on your development machine. This ends up being bad too. For instance, if it is not possible to do something in a specific rdbms, for instance, lets say blobs, Django will not be able to implement it because it has to support those several rdbms.
There are many hacks ( http://djangosnippets.org/snippets/1597/ ) but hacks will be hacks and you want your app to be reliable and not compromise your code quality right from the start, right?
Many field options have equivalents in Django (primary key, auto increment). You just have to find them. For auto increment there is AutoField. Primary key is an option of the base Field (so you can provide it as a keyword argument to any field).
Also if you want gis geometry data types (is that what you meant?) you can install and use geodjango.
2) A lot can be done by using the database manually. Django helps you a bit here, for instance it gives you access to the database cursor for raw SQL access to the database, supports custom fields, and every orm query "chain" (like MyModel.objects.all().filter(...)) can be incremented with raw SQL "where" and "select" clauses. But you might not want to be using Django or at least not its ORM.