django refuses view in postgres when migrating

I made views in postgesql an I’m trying to create models that use the views. Django refuses to migrate saying my view is not a table.
Django version 5.2.3
Posgres version 15.13
Python version 3.11.2

DDL in postgres

 SELECT cities_light_city.display_name,
    cities_light_city.name
   FROM cities_light_city
  WHERE cities_light_city.country_id = 13;

model:

class AussieCities(models.Model):
	name=models.CharField(max_length=200,primary_key=True)
	display_name=models.CharField(max_length=200)
	class Meta:
		managed=False
		db_table='public.Aussie_cities'

I tried with and without the public prefix. No change in the error.
Error:

/usr/lib/python3/dist-packages/requests/__init__.py:109: RequestsDependencyWarning: urllib3 (2.5.0) or chardet (5.1.0)/charset_normalizer (3.0.1) doesn't match a supported version!
  warnings.warn(
Operations to perform:
  Apply all migrations: admin, auth, cities_light, contenttypes, faq, sessions, tshirts
Running migrations:
  Applying tshirts.0008_aussiecities_alter_customer_city...Traceback (most recent call last):
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 103, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
psycopg.errors.WrongObjectType: referenced relation "Aussie_cities" is not a table

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/mnt/nvme_ssd/Aussie_projects/manage.py", line 22, in <module>
    main()
  File "/mnt/nvme_ssd/Aussie_projects/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 416, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 460, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 107, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 353, in handle
    post_migrate_state = executor.migrate(
                         ^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
            ^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 255, in apply_migration
    state = migration.apply(state, schema_editor)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/migration.py", line 132, in apply
    operation.database_forwards(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/operations/fields.py", line 241, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 912, in alter_field
    self._alter_field(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/postgresql/schema.py", line 274, in _alter_field
    super()._alter_field(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 1269, in _alter_field
    self.execute(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/postgresql/schema.py", line 48, in execute
    return super().execute(sql, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 204, in execute
    cursor.execute(sql, params)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 122, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
    with self.db.wrap_database_errors:
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 103, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
django.db.utils.ProgrammingError: referenced relation "Aussie_cities" is not a table

Migration file:

# Generated by Django 5.2.3 on 2025-07-19 11:40

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('tshirts', '0009_aussie_cities_alter_customer_city_and_more'),
    ]

    operations = [
        migrations.DeleteModel(
            name='Aussie_cities',
        ),
        migrations.CreateModel(
            name='AussieCities',
            fields=[
                ('name', models.CharField(max_length=200, primary_key=True, serialize=False)),
                ('display_name', models.CharField(max_length=200)),
            ],
            options={
                'db_table': 'public.Aussie_cities',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AussieRegions',
            fields=[
                ('name', models.CharField(max_length=200, primary_key=True, serialize=False)),
                ('display_name', models.CharField(max_length=200)),
            ],
            options={
                'db_table': 'public.Aussie_regions',
                'managed': False,
            },
        ),
        migrations.AlterField(
            model_name='customer',
            name='country',
            field=models.CharField(default='Australia', max_length=100),
        ),
        migrations.AlterField(
            model_name='customer',
            name='city',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='tshirts.aussiecities'),
        ),
        migrations.AlterField(
            model_name='customer',
            name='state_province',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='tshirts.aussieregions'),
        ),
    ]

the migrations.DeleteModel was orignally placed at the end ; I’ve put it in front to test but no change in the error.

Side note: That was not the complete DDL for that view - it is missing the CREATE VIEW ... clause. It is that clause within the DDL that would help me determine whether you actually created a view by that name. A “\dv” command in psql would also help determine the validity of the view name.

However, in this case, I’m going to guess that it’s not necessary because you’re trying to use an upper-case table or view name - and PostgreSQL converts all names to lower case unless it’s enclosed in double quotes. See PostgreSQL: Documentation: 17: 4.1. Lexical Structure

In other words, create view MyView as ... will create a view named myview. However, create view "MyView" as ... will create the view named MyView. And, you would also need to refer to that view double-quoted in the Meta class definition.

It is always my recommendation to keep all PostgreSQL objects as lower-case only. It avoids a lot of unintended issues.

It is the frist time i’m working with postgres, but when I run the view it gives me select * from “Aussie_cities” in pgadmin4

Verzonden vanaf Outlook voor Android

the \dv command says no relation found

Side note: There should not be any migration file associated with that view. With managed = False, you don’t need to use makemigrations on that app (at least not for that model), and there’s no migration operation that should occur when you run migrate.

Show evidence that you have this view defined as you are trying to reference it in your model. Show the complete ddl used to create the view. Show the output of the commands you’re using to verify that everything is created correctly. Show the output showing that the accounts attempting to use the view have permissions to access that view.

Not sure this is what you meant

-- View: public.Aussie_cities

-- DROP VIEW public."Aussie_cities";

CREATE OR REPLACE VIEW public."Aussie_cities"
 AS
 SELECT cities_light_city.display_name,
    cities_light_city.name
   FROM cities_light_city
  WHERE cities_light_city.country_id = 13;

ALTER TABLE public."Aussie_cities"
    OWNER TO webadmin;
COMMENT ON VIEW public."Aussie_cities"
    IS 'Cities of Australia';


SELECT * FROM public."Aussie_cities"

"Rockingham, Western Australia, Australia"	"Rockingham"
"Perth, Western Australia, Australia"	"Perth"
"Mount Isa, Queensland, Australia"	"Mount Isa"
"Mandurah, Western Australia, Australia"	"Mandurah"
"Kwinana, Western Australia, Australia"	"Kwinana"
"Geraldton, Western Australia, Australia"	"Geraldton"
"Gawler, South Australia, Australia"	"Gawler"
"Busselton, Western Australia, Australia"	"Busselton"
"Bunbury, Western Australia, Australia"	"Bunbury"
"Albany, Western Australia, Australia"	"Albany"
"Wodonga, Victoria, Australia"	"Wodonga"
"Warwick, Queensland, Australia"	"Warwick"
"Warrnambool, Victoria, Australia"	"Warrnambool"
"Warragul, Victoria, Australia"	"Warragul"
"Wangaratta, Victoria, Australia"	"Wangaratta"
"Tuggeranong Administrative District, Australian Capital Territory, Australia"	"Tuggeranong Administrative District"
"Traralgon, Victoria, Australia"	"Traralgon"
"Townsville, Queensland, Australia"	"Townsville"
"Toowoomba, Queensland, Australia"	"Toowoomba"
"Taree, New South Wales, Australia"	"Taree"
"Tamworth, New South Wales, Australia"	"Tamworth"
"Rockhampton, Queensland, Australia"	"Rockhampton"
"Port Macquarie, New South Wales, Australia"	"Port Macquarie"
"Newcastle, New South Wales, Australia"	"Newcastle"
"Narangba, Queensland, Australia"	"Narangba"
"Mount Gambier, South Australia, Australia"	"Mount Gambier"
"Mildura, Victoria, Australia"	"Mildura"
"Maryborough, Queensland, Australia"	"Maryborough"
"Maitland, New South Wales, Australia"	"Maitland"
"Mackay, Queensland, Australia"	"Mackay"
"Liverpool, New South Wales, Australia"	"Liverpool"
"Launceston, Tasmania, Australia"	"Launceston"
"Hornsby, New South Wales, Australia"	"Hornsby"
"Hobart, Tasmania, Australia"	"Hobart"
"Griffith, New South Wales, Australia"	"Griffith"
"Goulburn, New South Wales, Australia"	"Goulburn"
"Gold Coast, Queensland, Australia"	"Gold Coast"
"Gladstone, Queensland, Australia"	"Gladstone"
"Geelong, Victoria, Australia"	"Geelong"
"Frankston East, Victoria, Australia"	"Frankston East"
"Dubbo, New South Wales, Australia"	"Dubbo"
"Coffs Harbour, New South Wales, Australia"	"Coffs Harbour"
"Wollongong, New South Wales, Australia"	"Wollongong"
"Cessnock, New South Wales, Australia"	"Cessnock"
"Capalaba, Queensland, Australia"	"Capalaba"
"Cairns, Queensland, Australia"	"Cairns"
"Burnie, Tasmania, Australia"	"Burnie"
"Bundaberg, Queensland, Australia"	"Bundaberg"
"Broken Hill, New South Wales, Australia"	"Broken Hill"
"Bendigo, Victoria, Australia"	"Bendigo"
"Bathurst, New South Wales, Australia"	"Bathurst"
"Ballarat, Victoria, Australia"	"Ballarat"
"Bairnsdale, Victoria, Australia"	"Bairnsdale"
"Armidale, New South Wales, Australia"	"Armidale"
"Palmerston, Northern Territory, Australia"	"Palmerston"
"Hervey Bay, Queensland, Australia"	"Hervey Bay"
"Parramatta, New South Wales, Australia"	"Parramatta"
"Adelaide Hills, South Australia, Australia"	"Adelaide Hills"
"Balwyn North, Victoria, Australia"	"Balwyn North"
"Sunshine Coast, Queensland, Australia"	"Sunshine Coast"
"Darwin, Northern Territory, Australia"	"Darwin"
"Alice Springs, Northern Territory, Australia"	"Alice Springs"
"Adelaide, South Australia, Australia"	"Adelaide"
"Sydney, New South Wales, Australia"	"Sydney"
"Shepparton, Victoria, Australia"	"Shepparton"
"Orange, New South Wales, Australia"	"Orange"
"Melbourne, Victoria, Australia"	"Melbourne"
"Canberra, Australian Capital Territory, Australia"	"Canberra"
"Brisbane, Queensland, Australia"	"Brisbane"
"Logan City, Queensland, Australia"	"Logan City"
"St Albans, Victoria, Australia"	"St Albans"

Models :
`class Customer(models.Model):

customer_id=models.AutoField(primary_key=True)
user_id=models.ForeignKey(User,on_delete=models.SET_NULL,null=True,blank=True,help_text="Coupled user (when relevant)")
first_name=models.CharField(max_length=100)
last_name=models.CharField(max_length=100)
full_name=models.GeneratedField(expression=Concat(F("first_name"),Value(" "),F("last_name")),output_field=models.CharField(max_length=201),db_persist=True,verbose_name="Full name")
email=models.EmailField(verbose_name="E-mail address",unique=True,help_text="unique E-mail address of the customer")
phone_number=models.CharField(verbose_name="Cell phone number",max_length=20,blank=True,null=True)
address_line_1=models.CharField(max_length=255,blank=True,null=True)
address_line_2=models.CharField(max_length=255,blank=True,null=True)
postal_code=models.CharField(max_length=20,blank=True,null=True)
date_added=models.DateField(auto_now_add=True)
date_last_modified=models.DateField(auto_now=True)
is_active=models.BooleanField(verbose_name="Active",default=True)
company_name = models.CharField(max_length=100,blank=True,null=True)
tax_number = models.CharField(max_length=20,blank=True,null=True)
country=models.CharField(max_length=100,default='Australia')
city = models.ForeignKey('AussieCities', on_delete=models.SET_NULL, null=True, blank=True)
state_province = models.ForeignKey('AussieRegions', on_delete=models.SET_NULL, null=True, blank=True)

class Meta:
	verbose_name = "Customer"
	verbose_name_plural= "Customers"
	ordering= ["last_name","first_name"]
def __str__(self):
	return f"{self.first_name} {self.last_name} ({self.email})"
def get_full_name(self):
	return  f"{self.first_name} {self.last_name}".strip()
def get_address(self):
	parts= [self.address_line_1]
	if self.address_line_2:
		parts.append(self.address_line_2)
	parts.extend([self.city,self.postal_code,self.state_province,self.country])
	return ", ".join(filter(None,parts))

class AussieCities(models.Model):
name=models.CharField(max_length=200,primary_key=True)
display_name=models.CharField(max_length=200)
class Meta:
managed=False
db_table=“Aussie_cities”

class AussieRegions(models.Model):
name=models.CharField(max_length=200,primary_key=True)
display_name=models.CharField(max_length=200)
class Meta:
managed=False
db_table=“Aussie_regions”

`

Good!

Since you need to double-quote case-sensitive names in postgres, you would need to change this:

to this:
db_table = '"Aussie_cities"'

Note that the double quotes need to be part of the table name, not just being used as the string delimiter.

I used the capital letter out of habit. Since postgres rather works with lower case I removed the views and recreated them lower case only. But the error remains the same. Is the underscore a problem or do I have to put the name in double quotes?
‘aussie_cities’ or “aussie_cities”. In my model I have put ‘aussie_cities’.
It is a bit confusing because I use single quotes, the migration file uses single quotes but the error uses double quotes.

 referenced relation "aussie_cities" is not a table

Again, please provide the details. Show the updated model along with the modified view definition. Show the evidence that the view exists and is accessible by the account you’re trying to use with it.

ddl:

-- View: public.aussie_cities

-- DROP VIEW public.aussie_cities;

CREATE OR REPLACE VIEW public.aussie_cities
 AS
 SELECT cities_light_city.name,
    cities_light_city.display_name
   FROM cities_light_city
  WHERE cities_light_city.country_id = 13;

ALTER TABLE public.aussie_cities
    OWNER TO webadmin;

Models:

class Customer(models.Model):
	
	customer_id=models.AutoField(primary_key=True)
	user_id=models.ForeignKey(User,on_delete=models.SET_NULL,null=True,blank=True,help_text="Coupled user (when relevant)")
	first_name=models.CharField(max_length=100)
	last_name=models.CharField(max_length=100)
	full_name=models.GeneratedField(expression=Concat(F("first_name"),Value(" "),F("last_name")),output_field=models.CharField(max_length=201),db_persist=True,verbose_name="Full name")
	email=models.EmailField(verbose_name="E-mail address",unique=True,help_text="unique E-mail address of the customer")
	phone_number=models.CharField(verbose_name="Cell phone number",max_length=20,blank=True,null=True)
	address_line_1=models.CharField(max_length=255,blank=True,null=True)
	address_line_2=models.CharField(max_length=255,blank=True,null=True)
	postal_code=models.CharField(max_length=20,blank=True,null=True)
	date_added=models.DateField(auto_now_add=True)
	date_last_modified=models.DateField(auto_now=True)
	is_active=models.BooleanField(verbose_name="Active",default=True)
	company_name = models.CharField(max_length=100,blank=True,null=True)
	tax_number = models.CharField(max_length=20,blank=True,null=True)
	country_id =models.CharField(max_length=100,default='Australia')
	city = models.ForeignKey('AussieCities', on_delete=models.SET_NULL, null=True, blank=True)
	state_province = models.ForeignKey('AussieRegions', on_delete=models.SET_NULL, null=True, blank=True)

	class Meta:
		verbose_name = "Customer"
		verbose_name_plural= "Customers"
		ordering= ["last_name","first_name"]
	def __str__(self):
		return f"{self.first_name} {self.last_name} ({self.email})"
	def get_full_name(self):
		return  f"{self.first_name} {self.last_name}".strip()
	def get_address(self):
		parts= [self.address_line_1]
		if self.address_line_2:
			parts.append(self.address_line_2)
		parts.extend([self.city,self.postal_code,self.state_province,self.country_id])
		return ", ".join(filter(None,parts))

class AussieCities(models.Model):
	name=models.CharField(max_length=200,primary_key=True)
	display_name=models.CharField(max_length=200)
	class Meta:
		managed=False
		db_table='aussie_cities'
		
class AussieRegions(models.Model):
	name=models.CharField(max_length=200,primary_key=True)
	display_name=models.CharField(max_length=200)
	class Meta:
		managed=False
		db_table='aussie_regions'

Forms:

class CustomerForm(forms.ModelForm):
	regions= AussieRegions.objects.all()
	region_choices=[('name') for region in regions]
	selected_region = forms.ModelChoiceField(queryset=AussieRegions.objects.all(), widget=forms.Select)
	cities= AussieCities.objects.all()
	city_choices=[('name') for city in cities]
	selected_city = forms.ModelChoiceField(queryset=AussieCities.objects.all(), widget=forms.Select)
	
	class Meta:
		model = Customer
		fields = ["first_name","last_name","email","phone_number","address_line_1","address_line_2","city","state_province","postal_code","country_id","company_name","tax_number"]


class RegionForm(forms.ModelForm):
	 class Meta:
		 model= AussieRegions
		 fields=['display_name','name']
		 
class CityForm(forms.ModelForm):
	 class Meta:
		 model=AussieCities
		 fields=['display_name','name']

View:

def customerview(request):
	form=CustomerForm()
	if request.method == 'POST':
		form = CustomerForm(request.POST)
		if form.is_valid():
			customer.region=form.cleaned_data['selected_region']
			customer.city=form.cleaned_data['selected_city']
			customer = form.save()
			user=User.objects.filter(email=request.POST['email']).first()
			if user:
				customer.user_id_id=user.id
				customer.save()
				login(request,user)
				return redirect('/home')
		else:
			form= CustomerForm(user=request.user)
	return render(request,'registration/customer.html',{"form":form})

What happens if you run the Django shell (python manage.py shell), import your AussieCities model, and then run AussieCities.objects.all()?

What happens if you run the python manage.py dbshell to get a psql session, then run select * from aussie_cities;?

I get the expected result.
dbshell:

               name                 |                                 display_name                                 
-------------------------------------+------------------------------------------------------------------------------
 Rockingham                          | Rockingham, Western Australia, Australia
 Perth                               | Perth, Western Australia, Australia
 Mount Isa                           | Mount Isa, Queensland, Australia
 Mandurah                            | Mandurah, Western Australia, Australia
 Kwinana                             | Kwinana, Western Australia, Australia
 Geraldton                           | Geraldton, Western Australia, Australia
 Gawler                              | Gawler, South Australia, Australia
 Busselton                           | Busselton, Western Australia, Australia
 Bunbury                             | Bunbury, Western Australia, Australia
 Albany                              | Albany, Western Australia, Australia
 Wodonga                             | Wodonga, Victoria, Australia
 Warwick                             | Warwick, Queensland, Australia
 Warrnambool                         | Warrnambool, Victoria, Australia
 Warragul                            | Warragul, Victoria, Australia
 Wangaratta                          | Wangaratta, Victoria, Australia
 Tuggeranong Administrative District | Tuggeranong Administrative District, Australian Capital Territory, Australia
 Traralgon                           | Traralgon, Victoria, Australia
 Townsville                          | Townsville, Queensland, Australia
 Toowoomba                           | Toowoomba, Queensland, Australia
 Taree                               | Taree, New South Wales, Australia
 Tamworth                            | Tamworth, New South Wales, Australia
 Rockhampton                         | Rockhampton, Queensland, Australia
:

shell:

>>> import AussieCities
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ModuleNotFoundError: No module named 'AussieCities'
>>> AussieCities.objects.all()
<QuerySet [<AussieCities: Rockingham>, <AussieCities: Perth>, <AussieCities: Mount Isa>, <AussieCities: Mandurah>, <AussieCities: Kwinana>, <AussieCities: Geraldton>, <AussieCities: Gawler>, <AussieCities: Busselton>, <AussieCities: Bunbury>, <AussieCities: Albany>, <AussieCities: Wodonga>, <AussieCities: Warwick>, <AussieCities: Warrnambool>, <AussieCities: Warragul>, <AussieCities: Wangaratta>, <AussieCities: Tuggeranong Administrative District>, <AussieCities: Traralgon>, <AussieCities: Townsville>, <AussieCities: Toowoomba>, <AussieCities: Taree>, '...(remaining elements truncated)...']

import gives module not found?

AussieCitites isn’t a module.

The import would be something like `from whatever_app.models import AussieCities.

But, since the query is working, everything looks good then.

so cursor.py is generating a wrong query. That’s a bug right?

You’ve lost me here.

Your original question was asking whether Django can still recognize a view as a model.

You had the issue with the case sensitivity in the name, which you have now resolved.

Your last snippet demonstrates that Django does recognize the view as a model, and that a query on that model is working.

If you are still having an issue here, please provide all the pertinent details about it.

the problem is still the same. Migrate fails.

 File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
django.db.utils.ProgrammingError: referenced relation "aussie_cities" is not a table
e File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
django.db.utils.ProgrammingError: referenced relation "aussie_cities" is not a table
e

Ok, going back through this entire thread, it appears you have a different problem, here:

You cannot create a ForeignKey to a view. From PostgreSQL’s perspective, that doesn’t make sense. A view is not a “real” object in the database.

See the docs at PostgreSQL: Documentation: 17: 5.5. Constraints and PostgreSQL: Documentation: 17: 39.2. Views and the Rule System

I’m not using the views as pk , but now I get something that puzzles me even more:

eddys@PI5:/mnt/nvme_ssd/Aussie_projects $ python manage.py migrate
/usr/lib/python3/dist-packages/requests/__init__.py:109: RequestsDependencyWarning: urllib3 (2.5.0) or chardet (5.1.0)/charset_normalizer (3.0.1) doesn't match a supported version!
  warnings.warn(
Operations to perform:
  Apply all migrations: admin, auth, cities_light, contenttypes, faq, sessions, tshirts
Running migrations:
  Applying tshirts.0002_aussiecities_aussieregions_brand_custompermission_and_more...Traceback (most recent call last):
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 103, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
psycopg.errors.InvalidTextRepresentation: invalid input syntax for type bigint: "Test"

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/mnt/nvme_ssd/Aussie_projects/manage.py", line 22, in <module>
    main()
  File "/mnt/nvme_ssd/Aussie_projects/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 416, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 460, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/base.py", line 107, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 353, in handle
    post_migrate_state = executor.migrate(
                         ^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
            ^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 255, in apply_migration
    state = migration.apply(state, schema_editor)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/migration.py", line 132, in apply
    operation.database_forwards(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/migrations/operations/fields.py", line 241, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 912, in alter_field
    self._alter_field(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/postgresql/schema.py", line 274, in _alter_field
    super()._alter_field(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 1165, in _alter_field
    self.execute(
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/postgresql/schema.py", line 48, in execute
    return super().execute(sql, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 204, in execute
    cursor.execute(sql, params)
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 122, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
    with self.db.wrap_database_errors:
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/eddys/.local/lib/python3.11/site-packages/django/db/backends/utils.py", line 103, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eddys/.local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
django.db.utils.DataError: invalid input syntax for type bigint: "Test"

Don’t know where this comes from. I only have an empty test.py. Nowhere else there is a reference to anything called “Test” in my project.

Please post the output of a pip check and pip list -o commands.