Добавление Foreign Key в Django с использованием команды cur.execute()

Vladimirych

Новичок
Пользователь
Авг 7, 2020
12
1
3
Третью ночь бьюсь с проблемой и не сдвинулся ни на шаг. В документации описано как добавлять записи через консоль и там все получается. Запуская в консоли скрипт тоже все получается, а вот сделать так, чтобы база наполнялась при загрузке страницы не получается.

Я изолировал проблему, вот весь код. Необходимо, чтобы в таблицу City сам собой подставлялся foreign key для Country. Следуя примеру добавления записей из консоли я подставляю в качестве значения название класса, таким вот образом – (city, Country) – но получаю ошибку "Error binding parameter 1 - probably unsupported type.".

models.py
Код:
from django.db import models

class Country(models.Model) :
    name = models.CharField(max_length=64)

class City(models.Model) :
    name = models.CharField(max_length=64)
    country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True)

views.py
Код:
from django.shortcuts import render
import sqlite3
from unesco.models import Country

def db(request):
    conn = sqlite3.connect('db.sqlite3')
    cur = conn.cursor()

    country = 'Russia'
    cur.execute('''INSERT INTO unesco_country (name) VALUES ( ? )''', (country,))

    city = 'Saint Petersburg'
    cur.execute('''INSERT INTO unesco_city (name, country_id) VALUES ( ?, ? )''', (city, Country))

    conn.commit()

    return render(request, 'unesco/db.html')
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
получаю ошибку "Error binding parameter 1 - probably unsupported type.".
Ошибка возникает потому что вы в числовое поле country_id пытаетесь записать класс Country. Туда нужно записывать число.
Попробуйте так:
Python:
from django.shortcuts import render
import sqlite3
from unesco.models import Country

def db(request):
    conn = sqlite3.connect('db.sqlite3')
    cur = conn.cursor()

    country = 'Russia'
    cur.execute('''INSERT INTO unesco_country (name) VALUES ( ? )''', (country,))
    
    # rowid для sqlite (если не сработает попробуйте id вместо rowid)
    res = cur.execute('''SELECT rowid FROM unesco_country WHERE name=?''', (country,))
    c_id = res.fetchone()

    city = 'Saint Petersburg'
    cur.execute('''INSERT INTO unesco_city (name, country_id) VALUES ( ?, ? )''', (city, c_id[0]))

    conn.commit()

    return render(request, 'unesco/db.html')
Лучше конечно не делать прямые запросы в базу, а использовать ORM (экземпляры классов моделей).
 
  • Мне нравится
Реакции: Vladimirych

Vladimirych

Новичок
Пользователь
Авг 7, 2020
12
1
3
Получается, я как раз и смешал прямые запросы в базу из одного примера с ORM из другого примера, где не звучало такого названия, поэтому я и не понял, что это две разные вещи. Теперь работает, спасибо!

Код:
country = athlete_info['country']
c = Country(name=country)
c.save()

state = athlete_info['state']
s = State(name=state, country=c)
s.save()

city = athlete_info['city']
ct = City(name=city, state=s, country=c)
ct.save()
 

Vladimirych

Новичок
Пользователь
Авг 7, 2020
12
1
3
Ошибка возникает потому что вы в числовое поле country_id пытаетесь записать класс Country. Туда нужно записывать число.

Попробовал, все работает. Но теперь когда вы рассказали про ORM и правда нет смысла делать это таким путем.
 

Форум IT Специалистов