(fields.E300) Поле определяет связь с моделью «AbstractEmailUser», которая либо не установлена, либо является абстрактной

Я пытаюсь создать customuser для своего проекта Django с электронной почтой в качестве имени пользователя и добавить переключатель для грузовика и компании. так что в процессе регистрации адрес электронной почты будет зарегистрирован как для грузовика или компании. Я упомянул переключатель как «Тег» и добавил поле ManytoMany к тегу в модели EmailUser. Когда я делаю миграцию, возникает ошибка: (fields.E300) Поле определяет отношение с моделью «AbstractEmailUser», которая либо не установлена, либо является абстрактной.

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

модели.py:

import django
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager, PermissionsMixin)
from django.core.mail import send_mail
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _



class EmailUserManager(BaseUserManager):

"""Custom manager for EmailUser."""

def _create_user(self, email, password,
                 is_staff, is_superuser, **extra_fields):
    """Create and save an EmailUser with the given email and password.

    :param str email: user email
    :param str password: user password
    :param bool is_staff: whether user staff or not
    :param bool is_superuser: whether user admin or not
    :return custom_user.models.EmailUser user: user
    :raise ValueError: email is not set

    """
    now = timezone.now()
    if not email:
        raise ValueError('The given email must be set')
    email = self.normalize_email(email)
    is_active = extra_fields.pop("is_active", True)
    user = self.model(email=email, is_staff=is_staff, is_active=is_active,
                      is_superuser=is_superuser, last_login=now,
                      date_joined=now, **extra_fields)
    user.set_password(password)
    user.save(using=self._db)
    return user

def create_user(self, email, password=None, **extra_fields):
    """Create and save an EmailUser with the given email and password.

    :param str email: user email
    :param str password: user password
    :return custom_user.models.EmailUser user: regular user

    """
    is_staff = extra_fields.pop("is_staff", False)
    return self._create_user(email, password, is_staff, False,
                             **extra_fields)

def create_superuser(self, email, password, **extra_fields):
    """Create and save an EmailUser with the given email and password.

    :param str email: user email
    :param str password: user password
    :return custom_user.models.EmailUser user: admin user

    """
    return self._create_user(email, password, True, True,
                             **extra_fields)


class AbstractEmailUser(AbstractBaseUser, PermissionsMixin):

"""Abstract User with the same behaviour as Django's default User.

AbstractEmailUser does not have username field. Uses email as the
USERNAME_FIELD for authentication.

Use this if you need to extend EmailUser.

Inherits from both the AbstractBaseUser and PermissionMixin.

The following attributes are inherited from the superclasses:
    * password
    * last_login
    * is_superuser

"""

email = models.EmailField(_('email address'), max_length=255,
                          unique=True, db_index=True)

is_staff = models.BooleanField(
    _('staff status'), default=False, help_text=_(
        'Designates whether the user can log into this admin site.'))
is_active = models.BooleanField(_('active'), default=True, help_text=_(
    'Designates whether this user should be treated as '
    'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

objects = EmailUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []

class Meta:
    verbose_name = _('user')
    verbose_name_plural = _('users')
    abstract = True

# def __init__(self, *args, **kwargs):
    # super(AbstractEmailUser, self).__init__(*args, **kwargs)
    # if self.instance.pk:
            # self.fields['Tag'].initial = self.instance.Tag_set.all()

def get_full_name(self):
    """Return the email."""
    return self.email

def get_short_name(self):
    """Return the email."""
    return self.email

def email_user(self, subject, message, from_email=None, **kwargs):
    """Send an email to this User."""
    send_mail(subject, message, from_email, [self.email], **kwargs)


# Monkey patch Django 1.7 to avoid detecting migrations
if django.VERSION[:2] == (1, 7):
last_login = AbstractEmailUser._meta.get_field('last_login')
last_login.blank = True
last_login.null = True
last_login.default = models.fields.NOT_PROVIDED
groups = AbstractEmailUser._meta.get_field('groups')
groups.help_text = _('The groups this user belongs to. A user will get '
                     'all permissions granted to each of their groups.')


class EmailUser(AbstractEmailUser):

"""
Concrete class of AbstractEmailUser.

Use this if you don't need to extend EmailUser.

"""
CHOICES = (('Truck', 'Truck'),('Company', 'Company'),)
Tag = models.ManyToManyField(AbstractEmailUser)
class Meta(AbstractEmailUser.Meta):
    swappable = 'AUTH_USER_MODEL'

формы.py:

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.utils.translation import ugettext_lazy as _


class EmailUserCreationForm(forms.ModelForm):

"""A form for creating new users.

Includes all the required fields, plus a repeated password.

"""

error_messages = {
    'duplicate_email': _("A user with that email already exists."),
    'password_mismatch': _("The two password fields didn't match."),
}

password1 = forms.CharField(
    label=_("Password"),
    widget=forms.PasswordInput)
password2 = forms.CharField(
    label=_("Password confirmation"),
    widget=forms.PasswordInput,
    help_text=_("Enter the same password as above, for verification."))
CHOICES= (('Truck', 'Truck'),('Company', 'Company'),)
Tag = forms.ChoiceField(choices=CHOICES, label='Tag', widget=forms.RadioSelect())

class Meta:
    model = get_user_model()
    fields = ('email', 'Tag',)

def clean_email(self):
    """Clean form email.

    :return str email: cleaned email
    :raise forms.ValidationError: Email is duplicated

    """
    # Since EmailUser.email is unique, this check is redundant,
    # but it sets a nicer error message than the ORM. See #13147.
    email = self.cleaned_data["email"]
    try:
        get_user_model()._default_manager.get(email=email)
    except get_user_model().DoesNotExist:
        return email
    raise forms.ValidationError(
        self.error_messages['duplicate_email'],
        code='duplicate_email',
    )

def clean_password2(self):
    """Check that the two password entries match.

    :return str password2: cleaned password2
    :raise forms.ValidationError: password2 != password1

    """
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError(
            self.error_messages['password_mismatch'],
            code='password_mismatch',
        )
    return password2

def save(self, commit=True):
    """Save user.

    Save the provided password in hashed format.

    :return custom_user.models.EmailUser: user

    """
    user = super(EmailUserCreationForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user


class EmailUserChangeForm(forms.ModelForm):

"""A form for updating users.

Includes all the fields on the user, but replaces the password field
with admin's password hash display field.

"""

password = ReadOnlyPasswordHashField(label=_("Password"), help_text=_(
    "Raw passwords are not stored, so there is no way to see "
    "this user's password, but you can change the password "
    "using <a href=\"password/\">this form</a>."))

class Meta:
    model = get_user_model()
    exclude = ()

def __init__(self, *args, **kwargs):
    """Init the form."""
    super(EmailUserChangeForm, self).__init__(*args, **kwargs)
    f = self.fields.get('user_permissions', None)
    if f is not None:
        f.queryset = f.queryset.select_related('content_type')

def clean_password(self):
    """Clean password.

    Regardless of what the user provides, return the initial value.
    This is done here, rather than on the field, because the
    field does not have access to the initial value.

    :return str password:

    """
    return self.initial["password"]

admin.py:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _

from .forms import EmailUserChangeForm, EmailUserCreationForm
from .models import EmailUser


class EmailUserAdmin(UserAdmin):

"""EmailUser Admin model."""

fieldsets = (
    (None, {'fields': ('email', 'password', 'Tag')}),
    (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                   'groups', 'user_permissions')}),
    (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = ((
    None, {
        'classes': ('wide',),
        'fields': ('email', 'password1', 'password2', 'Tag')
    }
),
)

# The forms to add and change user instances
form = EmailUserChangeForm
add_form = EmailUserCreationForm

# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'is_staff', )
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups', 'Tag')
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ('groups', 'user_permissions', 'Tag',)

# Register the new EmailUserAdmin
admin.site.register(EmailUser, EmailUserAdmin)

person vanam    schedule 04.07.2016    source источник
comment
У вас есть поле выбора в вашей форме с CHOICES= (('Truck', 'Truck'),('Company', 'Company'),), но у вас есть поле многие ко многим в вашей модели, что является чем-то совершенно другим. Что вы пытаетесь сделать здесь?   -  person Alasdair    schedule 04.07.2016
comment
Изначально я написал Tag = models.CharField(choices=CHOICES, max_length=20). Но когда я выполняю миграцию, возникает ошибка, filter_horizontal в вашем admin.py должно быть полем «многие ко многим», и поэтому я изменил его поле «многие на многие».   -  person vanam    schedule 04.07.2016
comment
Параметр filter_horizontal предназначен только для полей «многие ко многим». Если ваши данные представляют собой CharField, вы должны придерживаться CharField, вы не должны менять его на поле «многие ко многим» только для того, чтобы использовать filter_horizontal.   -  person Alasdair    schedule 04.07.2016
comment
Итак, как можно избавиться от возникшей ошибки, чтобы создать множество полей для filter_horizontal, состоящих из ('groups', 'user_permissions', 'Tag',).   -  person vanam    schedule 04.07.2016
comment
Если Tag не является полем "многие ко многим", то его не должно быть в filter_horizontal. Итак, у вас должно быть filter_horizontal = ('groups', 'user_permissions').   -  person Alasdair    schedule 04.07.2016
comment
Привет, у меня похожая ситуация: здесь: (stackoverflow.com/questions/39566144/). Вам удалось разобраться? Не могли бы вы взглянуть и на мою ситуацию?   -  person Dr Confuse    schedule 19.09.2016