Denial of service and traffic overload are two different things, so using a traffic generator isn't really the way to go. Traffic generators are great to model real-world usage of a resource (e.g. users coming at random times (Poisson distribution), random or recorded navigation templates, common searches and errors...). Most DDoSes are little more than GET / HTTP/1.0
, but in job lots. Large job lots. That's not real "traffic".
If you want to see what happens when the system gets DoSed and exhausts its resources, you can e.g. disable SYN half-open protection (SYN cookies) if present, and use some DoS utility to fake opening connections. Or keep the connection open through, say, a Perl script.
Or you can send requests to those endpoints with a higher system load (e.g. that need database querying).
Malformed data will in all likelihood be intercepted at the outer layers of the Django router (if not by WSGI itself) and generate the least load. It depends on the malformation, of course.
Slowing down the send rate should stress Apache more than the rest of the stack (Django sends its output in fire-and-forget mode), while pulsing requests should hit Django more heavily, especially if they're crafted against the more expensive endpoints.