2016-05-06 3 views
2

Я удалил свой db.sqlite3 и файл в моей папке миграции, кроме __init__.py, но включая папку __pycache__.ValueError по значению по умолчанию для внешнего ключа

Мое приложение - это несколько файлов в папке с файлом __init__.py с некоторым импортом и переменной __all__ (я не знаю, если это так).

Из приглашения я даю первую команду перехода, и она выглядит для работы (перенос сеансов, admin, auth, registration, contenttypes. Не существует моего приложения «ядро»).

Итак, я даю команду makemigrations и снова команду migrate. На этот раз он дает ошибку:

ValueError: invalid literal for int() with base 10: 'basic' 

В модели есть более ForeignKey поля с по умолчанию = «основной». basic будет объектом связанного класса, но на самом деле его не существует (до того, как я создам базу данных, тогда я ее заполню). Я думаю, это нормально.

Во всяком случае я изменить в неплатеже = 1, и он работает (но 1 не будет объектом, так что это не так!)

Мои model:

Class Payment(models.Model): 
    name = models.CharField(max_length=32) 

Class ProfileUser(models.Model): 
    payment = models.ForeignKey(Payment, blank=True, null=True, 
     default='basic', on_delete=models.PROTECT) 
    #etc 

Существует способ использовать «основной «? Я предпочитаю не использовать id = 1, потому что я не уверен, что знаю идентификатор, который будет иметь базовый (помните, что он еще не существует).

Btw в других моделях у меня есть, так и ситуации, они появляются в работах ...

Вся ошибка:

(myvenv) c:\Python34\Scripts\possedimenti\sitopossedimenti>manage.py migrate 
Operations to perform: 
    Apply all migrations: contenttypes, core, registration, admin, auth, sessions 
Running migrations: 
    Rendering model states... DONE 
    Applying core.0001_initial...Traceback (most recent call last): 
    File "C:\Python34\Scripts\possedimenti\sitopossedimenti\manage.py", line 10, i 
n <module> 
    execute_from_command_line(sys.argv) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma 
nagement\__init__.py", line 353, in execute_from_command_line 
    utility.execute() 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma 
nagement\__init__.py", line 345, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma 
nagement\base.py", line 348, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma 
nagement\base.py", line 399, in execute 
    output = self.handle(*args, **options) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma 
nagement\commands\migrate.py", line 200, in handle 
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr 
ations\executor.py", line 92, in migrate 
    self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_ini 
tial) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr 
ations\executor.py", line 121, in _migrate_all_forwards 
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_ 
initial) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr 
ations\executor.py", line 198, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr 
ations\migration.py", line 123, in apply 
    operation.database_forwards(self.app_label, schema_editor, old_state, projec 
t_state) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr 
ations\operations\fields.py", line 62, in database_forwards 
    field, 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back 
ends\sqlite3\schema.py", line 221, in add_field 
    self._remake_table(model, create_fields=[field]) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back 
ends\sqlite3\schema.py", line 103, in _remake_table 
    self.effective_default(field) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back 
ends\base\schema.py", line 210, in effective_default 
    default = field.get_db_prep_save(default, self.connection) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode 
ls\fields\related.py", line 912, in get_db_prep_save 
    return self.target_field.get_db_prep_save(value, connection=connection) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode 
ls\fields\__init__.py", line 728, in get_db_prep_save 
    prepared=False) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode 
ls\fields\__init__.py", line 968, in get_db_prep_value 
    value = self.get_prep_value(value) 
    File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode 
ls\fields\__init__.py", line 976, in get_prep_value 
    return int(value) 
ValueError: invalid literal for int() with base 10: 'basic' 

Спасибо

PS: Я использую Python 3.4 Django 1.9 Windows7

ответ

2

В вашей модели Payment вы явно не указали первичный ключ. Поэтому django создаст для вас. Это будет целое число автоматического прироста.

Class Payment(models.Model): 
    name = models.CharField(max_length=32) 

Теперь, когда вы определили Payment в качестве внешнего ключа для ProfileUser, Джанго считает, что это должно быть первичным ключом в Payment, которые должны быть использованы в качестве ссылки.

Class ProfileUser(models.Model): 
    payment = models.ForeignKey(Payment, blank=True, null=True, 
     default='basic', on_delete=models.PROTECT) 
    #etc 

Для обеспечения соблюдения этой ссылки поле платежа должно быть целым числом. И вы не можете вставить «basic» в целое поле.

Одним из решений является использование опции ForeignKey.to_field, чтобы явно ссылаться на другое поле в классе «Оплата».

ForeignKey.to_field¶ The field on the related object that the relation is to. By default, Django uses the primary key of the related object.

Таким образом, ваш класс станет

Class ProfileUser(models.Model): 
    payment = models.ForeignKey(Payment, blank=True, null=True, 
     default='basic', on_delete=models.PROTECT, 
     to_field = 'name') 
    #etc 

Теперь поле оплаты здесь становится CharField. Обратите внимание, что в большинстве случаев было бы более эффективно использовать целое поле в качестве внешнего ключа.

Другая возможность - определить поле name в Payment как первичный ключ.

+0

Хорошо, спасибо, это работает, но 'to_field = 'name'' с' ' – fabio

+0

Упс да надзора. Будет исправлено. – e4c5

+0

Извините мой английский, мой комментарий может выглядеть грубым, но я искал подтверждение :) – fabio

2

Создайте функцию для возврата идентификатора (поставьте его перед сменой ProfileUser).

def get_basic_id(): 
    payment = Payment.options.get(name='basic') 
    return payment.id 

Class ProfileUser(models.Model): 
    payment = models.ForeignKey(Payment, blank=True, null=True, 
     default=get_basic_id(), on_delete=models.PROTECT) 

Хотя, если вы не знаете, что идентификатор «базовый» будет иметь, вы уверены, что она будет находиться в базе данных? Один из способов - заполнить таблицу платежей с помощью светильников.

https://docs.djangoproject.com/en/1.9/howto/initial-data/

+0

Он будет в базе данных, и если не все равно, я должен решить, какой по умолчанию использовать и редактировать поле. Если вы хотите взглянуть на этот связанный вопрос [link] (http://stackoverflow.com/questions/37076858/prepopulate-database-with-fixtures-or-with-script) – fabio