PostgreSQL е "силно въведен" - тоест всяка стойност във всяка заявка има определен тип, дефиниран изрично (например типът на колона в таблица) или имплицитно (например стойностите, въведени в WHERE клауза). Всички функции и оператори, включително = , трябва да бъдат дефинирани като приемащи специфични типове - така че например има оператор за VarChar = VarChar и различен за int = int .
Във вашия случай имате колона, която е изрично дефинирана като тип int , но го сравнявате със стойност, която PostgreSQL е интерпретирала като тип text .
SQLite, от друга страна, е "слабо въведен" - стойностите се третират свободно като тип, който най-добре отговаря на извършваното действие. Така че във вашата dev SQLite база данни операцията '42' = 42 може да се изчисли добре, където PostgreSQL ще се нуждае от конкретна дефиниция на VarChar = int (или text = int , text е типът за неограничени низове в PostgreSQL).
Сега PostgreSQL ще понякога бъдете полезни и автоматично „прехвърляйте“ стойностите си, за да накарате типовете да съответстват на известен оператор, но по-често, както се казва в намека, трябва да го правите изрично. Ако сами пишете SQL, изричен случай на тип може да изглежда като WHERE id = CAST('42' AS INT) (или WHERE CAST(id AS text) = '42' ).
Тъй като не сте, трябва да се уверите, че входът, който давате на генератора на заявки, е действително цяло число, а не просто низ, който се състои от цифри. Подозирам, че това е толкова просто, колкото използването на fields.IntegerField вместо fields.CharField , но всъщност не познавам Django или дори Python, така че реших да ви дам фона с надеждата, че можете да го вземете оттам.