Думайте о моделях, которые вы определяете как технические характеристики. Вы указываете нужные поля, и когда Django возвращает вам экземпляр, он использует ваши спецификации для создания совершенно другого объекта, который выглядит одинаково.
Например,
field1 = models.CharField()
Когда вы присваиваете значение field1, например «Я поле», не кажется ли вам странным, что вы можете присвоить строку полю, которое должно быть «CharField»? Но когда вы сохраняете этот экземпляр, все по-прежнему работает?
Django смотрит на CharField, говорит: «Это должна быть строка» и передает ее вам. Когда вы сохраняете его, Django проверяет значение по заданной вами спецификации и сохраняет его, если оно действительно.
Конечно, это очень упрощенное представление, но оно должно подчеркивать разницу между определением модели и фактическим экземпляром, с которым вы можете работать.