2016-05-04 9 views
1

Я новичок в форуме, и у меня есть проблема.Модели отношений Django с пользовательской моделью

в Django im пытается создать класс UserProfile путем ссылки на него с помощью OnetoOneField на объект пользователя. Когда я пытаюсь выполнить миграцию, я получаю:

«Вы пытаетесь добавить недействительное поле« id »к автору без по умолчанию, мы не можем этого сделать (базе данных необходимо что-то заполнить существующие строки). Пожалуйста, выберите исправление: 1) Обеспечить одноразовую по умолчанию сейчас (будет установлен на всех существующих строк) 2) Закройте, и позвольте мне добавить по умолчанию в models.py»

Я понимаю, что там некоторые поля в модели пользователя (например, «id»), которые не могут быть пустыми.

Когда я пытаюсь установить значение по умолчанию, оно будет makemigrations, но миграция завершится с ошибкой синтаксиса.

Мой вопрос: как разрешить Null или установить по умолчанию, который работает, без написания пользовательского класса User, и это возможно?

Я бы очень признателен за любую помощь в этом.

Вот мой код:

from django.db import models 
from django.contrib.auth.models import User as User_django 

class User(User_django): 
    pass 

class Author(models.Model): 
    user = models.OneToOneField(User, null=True) 

class BaseElement(models.Model): 

    author=models.ForeignKey(Author, null=True) 
    upvotes = models.PositiveIntegerField(default=0) 
    downvotes = models.PositiveIntegerField(default=0) 
    created = models.DateTimeField(auto_now_add=True, null=True) 

    def vote_up(self): 
     self.upvotes.value = self.upvotes.value + 1 

    def vote_down(self): 
     self.downvotes.value = self.downvotes.value + 1 

    class Meta: 
     abstract = True 


class Post(BaseElement): 
    content = models.TextField(max_length=240) 
    tags = models.CharField(max_length=40, blank=True) 
    said_by = models.CharField(max_length=40) 
    said_at = models.CharField(max_length=40, blank=True) 

    def get_comments(self): 
     return self.comment_set.all() 

    def get_comments_anzahl(self): 
     return self.comment_set.all().count() 


class Comment(BaseElement): 
    content = models.TextField(max_length=140) 
    commented_post = models.ForeignKey(Post, related_query_name="comment", null=True) 

EDIT:

Это происходит, если я пытаюсь установить значение по умолчанию и попытаться перенести:

You are trying to add a non-nullable field 'id' to author without a 
default; we can't do that (the database needs something to populate 
existing rows). 
Please select a fix: 
1) Provide a one-off default now (will be set on all existing rows) 
2) Quit, and let me add a default in models.py 
Select an option: 1 
Please enter the default value now, as valid Python 
The datetime and django.utils.timezone modules are available, so you can 
do e.g. timezone.now() 
>>> 1 
Migrations for 'post': 
0003_auto_20160505_1237.py: 
    - Change Meta options on author 
    - Change managers on author 
    - Remove field user_ptr from author 
    - Add field id to author 
    - Add field user to author 

Operations to perform: 
Apply all migrations: contenttypes, admin, sessions, post, auth 
Running migrations: 
    Rendering model states... DONE 
    Applying post.0003_auto_20160505_1237...Traceback (most recent call last): 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute 
    return Database.Cursor.execute(self, query, params) 
    sqlite3.OperationalError: near ")": syntax error 

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

Traceback (most recent call last): 
    File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django /core/management/__init__.py", line 353, in execute_from_command_line 
    utility.execute() 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute 
    output = self.handle(*args, **options) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle 
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 92, in migrate 
    self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards 
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 198, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/migration.py", line 123, in apply 
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 121, in database_forwards 
    schema_editor.remove_field(from_model, from_model._meta.get_field(self.name)) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 247, in remove_field 
    self._remake_table(model, delete_fields=[field]) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 197, in _remake_table 
    self.quote_name(model._meta.db_table), 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 110, in execute 
    cursor.execute(sql, params) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute 
    return super(CursorDebugWrapper, self).execute(sql, params) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__ 
    six.reraise(dj_exc_type, dj_exc_value, traceback) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise 
    raise value.with_traceback(tb) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute 
    return Database.Cursor.execute(self, query, params) 
    django.db.utils.OperationalError: near ")": syntax error 

EDIT: Похоже, я решили его, создав новый проект и пошаговое копирование моделей и миграцию. Все еще интересно, что там происходит, потому что я покраснел базу данных и несколько раз удалил файлы миграции и все еще бросал ошибки.

Спасибо за помощь!

+1

Вы должны показать, как вы пытались установить значение по умолчанию, и полученную вами ошибку. –

+1

Он также может помочь удалить любые проблемные миграции и восстановить их с нуля в новой базе данных. –

+0

Действительно, способ перебора для решения таких проблем состоит в том, чтобы: 1) удалить базу данных; 2) вручную удалить все файлы миграции в папке миграции (просто не удаляйте '__init __. Py'); 3) создать пустую базу данных; 4) 'python mange.py makemigrations'; 'python manage.py migrate'. –

ответ

0

просто импортировать Джанго встроенных User модели, как это:

from django.contrib.auth.models import User 

и удалить эту строку:

class User(User_django): 
    pass 

из вашего кода, как это совершенно не нужно.

UPDATE: Также похоже, что ваша проблема не имеет ничего общего с моделью User. Я думаю, что вы каким-то образом добавили поле id в свою модель Author и удалили ее (возможно, после неудачной миграции). Если это так, то вы можете отредактировать свой 0003_auto_20160505_1237.py. Для этого откройте его и удалите строки, которые выглядят примерно так:

migrations.AddField(
    model_name='author', 
    name='id', 
    field=models.someFieldType(options)), 
), 

и повторите попытку.

+0

Автор кажется довольно бессмысленным, также. –

+0

Спасибо за ваш ответ, у меня просто был этот класс, чтобы попытаться установить значения по умолчанию для полей пользователя, которые были недействительны, но поля столкнулись. После удаления и просто сохранения Author (для целей Userprofile) я все равно получаю ту же проблему. Django запрашивает значение по умолчанию для user.id, но что там есть и приемлемое значение? Если я установил Sting как «default», он будет makemigrations, но миграция завершится с «django.db.utils.OperationalError: near») »: синтаксическая ошибка» – jaidmin

+0

Похоже, что ваша проблема не имеет ничего общего с моделью «Пользователь». Я думаю, что вы каким-то образом добавили поле id в свою модель «Author» и удалили его (возможно, после неудачной миграции), не так ли? – sehrob

1

Взгляните на это:

https://docs.djangoproject.com/es/1.9/topics/db/examples/one_to_one/

Ваш код один к одному с пользователем. Когда вы устанавливаете его, это подразумевает удаление CASCADE и, следовательно, никогда не может быть нулевым.

если вы переходите на «один ко многим» и просто убедитесь, что вы вставляете только один объект для внешнего ключа, он будет работать. В противном случае измените свое каскадное правило.

Я скажу, однако, что это не очень хорошая идея, потому что если вы сделаете это null, что отделяет его от других записей. Рассмотрим второе поле PK.

Удачи.

Смежные вопросы