Объект NoneType не имеет атрибута _meta при изменении моделей - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь реструктурировать свои модели базы данных, чтобы включить в них больше данных, чем django.contrib.auth.models.User. Однако внесение изменений в models.py и views.py, а затем запуск python manage.py makemigrations не обновляет мои миграции должным образом. По-видимому, Джанго все еще думает, что я использую модель прокси.

Мне пришлось изменить users/migrations/0001_initial.py, чтобы избежать ошибки зависимости, затем я запустил python manage.py makemigrations и получил No changes detected.

users/migrations/0001_initial.py (до изменений)

# Generated by Django 2.2 on 2019-05-01 03:13

from django.db import migrations
import users.managers


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('auth', '0011_update_proxy_permissions'),
    ]

    operations = [
        migrations.CreateModel(
            name='Person',
            fields=[
            ],
            options={
                'proxy': True,
                'constraints': [],
                'indexes': [],
            },
            bases=('auth.user',),
            managers=[
                ('objects', users.managers.PersonManager()),
            ],
        ),
    ]

users/migrations/0001_initial.py (после изменений)

# Generated by Django 2.2 on 2019-05-01 03:13

from django.db import migrations
import users.managers


class Migration(migrations.Migration):

    initial = True

    dependencies = []

    operations = []


users/models.py (до изменений)

from django.db import models
from django.contrib.auth.models import User
from . import managers

class Person(User):
    objects = managers.PersonManager()

    class Meta:
        proxy = True

users/models.py (после изменений)

from django.db import models
from django.contrib.auth.models import User
from users import managers

class Profile:
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.CharField(max_length=30)
    objects = managers.ProfileManager()

users/views.py

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from users.models import Profile

def index(request):
    profile = Profile.objects.get(user_pk=request.session['id']) \
        if 'id' in request.session else None

    return render(request, 'users/index.html', {
        'profile': profile,
    })


def login(request):
    valid, response = Profile.objects.login_register(request, 'login')

    if not valid:
        for error in response:
            messages.error(request, error)
        return redirect('users:index')

    profile = Profile.objects.get(pk=response)
    messages.success(request, 'Welcome back, %s!' % profile.user.first_name)
    request.session['id'] = response
    return redirect('users:index')


def register(request):
    valid, response = Profile.objects.login_register(request, 'register')

    if not valid:
        for error in response:
            messages.error(request, error)
        return redirect('users:index')

    messages.success(request, 'You have successfully created an account.')
    request.session['id'] = response
    return redirect('users:index')


def logout(request):
    del request.session['id']

    messages.success(request, 'You have successfully logged out.')
    return redirect('users:index')

Когда я пытаюсь войти или зарегистрироваться, я ожидаю перезагрузки страницы с измененной формой входа / регистрации на страницу профиля пользователя.

Сообщение об ошибке

Internal Server Error: /profile/
Traceback (most recent call last):
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/matt/Repositories/pharmasseuse/users/views.py", line 12, in index
    if 'id' in request.session else None
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/query.py", line 399, in get
    clone = self.filter(*args, **kwargs)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/query.py", line 892, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1290, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
    split_subq=split_subq, simple_col=simple_col,
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1190, in build_filter
    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1049, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/home/matt/Repositories/pharmasseuse/env/lib/python3.5/site-packages/django/db/models/sql/query.py", line 297, in get_meta
    return self.model._meta
AttributeError: 'NoneType' object has no attribute '_meta'

Любая помощь приветствуется.

1 Ответ

1 голос
/ 07 июня 2019

Я не думаю, что это хорошая идея, чтобы изменить файлы миграции. Вы можете внести изменения в модель напрямую, и после изменения модели запустите ./manage.py makemigrations, чтобы сгенерировать новые файлы миграции.

Кроме того, вам нужно создать подкласс класса модели из models.Model:

class Profile<b>(models.Model)</b>:
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.CharField(max_length=30)
    objects = managers.ProfileManager()

Обновление

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

  1. Оставьте ProfileManager и PersonManager в users.manager, затем выполните makemigrations.
  2. Обновите файл миграции следующим образом (удалите атрибут manager из словаря):
# Generated by Django 2.2 on 2019-05-01 03:13

from django.db import migrations
import users.managers


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('auth', '0011_update_proxy_permissions'),
    ]

    operations = [
        migrations.CreateModel(
            name='Person',
            fields=[
            ],
            options={
                'proxy': True,
                'constraints': [],
                'indexes': [],
            },
            bases=('auth.user',),
            <b># managers=[
            #     ('objects', users.managers.PersonManager()),
            # ],</b>
        ),
    ]
...