#django #foreign-keys #django-queryset
Вопрос:
Я уже использовал набор запросов раньше, хотя это моя первая попытка объединить таблицы, но пока она не работает. Я использую django 3.2 и python 3.8.1
мой models.py
class Mainjoinbook(models.Model):
fullsitename = models.TextField(primary_key=True)
creationdate = models.DateTimeField()
entrytypeid = models.BigIntegerField(blank=True, null=True)
title = models.TextField(blank=True, null=True)
tickettype = models.TextField(blank=True, null=True)
ticket = models.TextField(blank=True, null=True)
status = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'mainlogbook'
class Sitelocation(models.Model):
site_name = models.TextField(primary_key=True)
latitude = models.TextField(blank=True, null=True)
longitude = models.TextField(blank=True, null=True)
sites = models.ForeignKey(Mainjoinbook, on_delete=models.DO_NOTHING)
class Meta:
managed = False
db_table = 'tblsiteaccess'
Я пытаюсь объединить все значения из обеих таблиц в моей views.py
qrylocations = Sitelocation.objects.select_related('sites').filter(sites__status='OPEN')
это приводит к этой ошибке, так как этот столбец создан django, но не принадлежит таблице. Я все еще не могу понять, как решить эту проблему, так как я перепробовал много вариантов, но всегда попадаю в какую-то ошибку, и я надеюсь, что кто-то может помочь мне понять, что я делаю неправильно при объединении таблиц с определенными первичными ключами
psycopg2.errors.UndefinedColumn: column tblsiteaccess.sites_id does not exist
вывод SQL показан следующим образом.
вывод из qrylocations.запрос
SELECT "tblsiteaccess"."site_name", "tblsiteaccess"."latitude", "tblsiteaccess"."longitude", "tblsiteaccess"."sites_id", "mainlogbook"."fullsitename", "mainlogbook"."log_id", "mainlogbook"."creationdate", "mainlogbook"."entrytypeid", "mainlogbook"."title", "mainlogbook"."tickettype", "mainlogbook"."ticket", "mainlogbook"."status" FROM "tblsiteaccess" INNER JOIN "mainlogbook" ON ("tblsiteaccess"."sites_id" = "mainlogbook"."fullsitename") WHERE "mainlogbook"."status" = OPEN
Комментарии:
1. Вы сделали эту таблицу с помощью
inspectdb
? Знаете ли вы фактическое имя столбца внешнего ключаsites
в таблицеtblsiteaccess
?2. Если вы создадите a
ForeignKey
, то Django обычно добавит_id
имя для соответствующего столбца в базе данных.3. да @AbdulAzizBarkat, таблицы в моделях взяты из
inspectdb
.sites
столбец был только для внешнего ключа, его нет в таблице. Я ожидаю получитьJOIN ON "tblsiteaccess"."site_name" = "mainlogbook"."fullsitename"
, что, очевидно, я делаю это неправильно4. @engstuff это не очень хороший первичный ключ, что происходит, когда кто-то хочет изменить имя
Mainjoinbook
объекта? Это неэффективно…
Ответ №1:
A ForeignKey
, естественно, нуждается в столбце в таблице базы данных. Поскольку site_name
сам по себе является первичным ключом, вы должны использовать его как ForeignKey
здесь, вместо этого вместо ForeignKey
этого должен быть OneToOneField
[Django docs], поскольку он также является первичным ключом и должен быть уникальным:
class Sitelocation(models.Model):
site_name = models.OneToOneField(
Mainjoinbook,
on_delete=models.CASCADE,
primary_key=True,
db_column='site_name'
)
latitude = models.TextField(blank=True, null=True)
longitude = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tblsiteaccess'
Комментарии:
1. спасибо @Абдул Азиз Баркат , как я уже сказал, я знал, что делаю что-то не так, и чтение всех документов сбивало меня с толку еще больше. это помогло мне намного лучше понять, как работает иностранный ключ