Yesterday I wrote about recognizing a database design pattern — one parent record describing an event, child records describing individual outcomes — across three different features in EduTrack without being told to. Fee/FeePayment. Attendance/AttendanceRecord. And then Assessment/AssessmentRecord for student test scores.

Today I built that third one properly. A Assessment knows what subject, what class, what type of test, what the max score is. An AssessmentRecord knows which student, what score, linked back to its parent. Clean shape, validated correctly — a score can't exceed the assessment's actual max score, and a student can't have two records for the same test.

Then I asked an AI tool to generate some Django admin code so I could manage assessments and scores through the built-in admin panel instead of building a custom interface for it.

It looked good. Properly structured, nice comments, even handled an edge case I hadn't thought of — showing an empty student dropdown for brand-new assessments instead of loading the entire school's student list.

It also had three real bugs:

  1. It referenced the wrong model entirely — nesting the parent model inside itself instead of the child model.
  2. It filtered students by subject through an indirect join, when my Assessment model already stores the exact class directly. A subject like Mathematics is taught across multiple classes — so this filter would've shown students from classes that had nothing to do with this specific assessment.
  3. The "is this ready to filter" condition checked a different field than the one actually being used to filter.

None of these would have crashed loudly. They would have shipped, looked like they worked in a casual test, and quietly shown a teacher the wrong group of students months from now.

I caught all three by asking one question at each step: what is this code actually trying to achieve, and does this specific line achieve that, or something adjacent to it? Not "does this look reasonable" — does it match the actual goal.

The pattern recognition from yesterday made this easier today. I knew exactly what shape the correct code should have, because I'd built it correctly twice before. That's what let me spot where the generated code drifted from it.

AI-generated code is a draft, not an answer. The understanding has to be yours either way.