简体   繁体   中英

Django makemigrations error when there are 3 custom model in a models.py

I got the following error when I tried to run makemigrations.

ERRORS:
remoshin_manager_sys.RemoshinDoctor.groups: (fields.E304) Reverse accessor for 'RemoshinDoctor.groups' clashes with reverse accessor for 'RemoshinManager.groups'.
HINT: Add or change a related_name argument to the definition for 'RemoshinDoctor.groups' or 'RemoshinManager.groups'.

remoshin_manager_sys.RemoshinDoctor.groups: (fields.E304) Reverse accessor for 'RemoshinDoctor.groups' clashes with reverse accessor for 'RemoshinUser.groups'.
HINT: Add or change a related_name argument to the definition for 'RemoshinDoctor.groups' or 'RemoshinUser.groups'.

remoshin_manager_sys.RemoshinDoctor.user_permissions: (fields.E304) Reverse accessor for 'RemoshinDoctor.user_permissions' clashes with reverse accessor for 'RemoshinManager.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'RemoshinDoctor.user_permissions' or 'RemoshinManager.user_permissions'.

remoshin_manager_sys.RemoshinDoctor.user_permissions: (fields.E304) Reverse accessor for 'RemoshinDoctor.user_permissions' clashes with reverse accessor for 'RemoshinUser.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'RemoshinDoctor.user_permissions' or 'RemoshinUser.user_permissions'.


remoshin_manager_sys.RemoshinManager.groups: (fields.E304) Reverse accessor for 'RemoshinManager.groups' clashes with reverse accessor for 'RemoshinDoctor.groups'.
HINT: Add or change a related_name argument to the definition for 'RemoshinManager.groups' or 'RemoshinDoctor.groups'.

remoshin_manager_sys.RemoshinManager.groups: (fields.E304) Reverse accessor for 'RemoshinManager.groups' clashes with reverse accessor for 'RemoshinUser.groups'.

HINT: Add or change a related_name argument to the definition for 'RemoshinManager.groups' or 'RemoshinUser.groups'.
remoshin_manager_sys.RemoshinManager.user_permissions: (fields.E304) Reverse accessor for 'RemoshinManager.user_permissions' clashes with reverse accessor for 'RemoshinDoctor.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'RemoshinManager.user_permissions' or 'RemoshinDoctor.user_permissions'.   
remoshin_manager_sys.RemoshinManager.user_permissions: (fields.E304) Reverse accessor for 'RemoshinManager.user_permissions' clashes with reverse accessor for 'RemoshinUser.user_permissions'.




HINT: Add or change a related_name argument to the definition for 'RemoshinManager.user_permissions' or 'RemoshinUser.user_permissions'.
remoshin_manager_sys.RemoshinUser.groups: (fields.E304) Reverse accessor for 'RemoshinUser.groups' clashes with reverse accessor for 'RemoshinDoctor.groups'.

HINT: Add or change a related_name argument to the definition for 'RemoshinUser.groups' or 'RemoshinDoctor.groups'.
remoshin_manager_sys.RemoshinUser.groups: (fields.E304) Reverse accessor for 'RemoshinUser.groups' clashes with reverse accessor for 'RemoshinManager.groups'.

HINT: Add or change a related_name argument to the definition for 'RemoshinUser.groups' or 'RemoshinManager.groups'.
remoshin_manager_sys.RemoshinUser.user_permissions: (fields.E304) Reverse accessor for 'RemoshinUser.user_permissions' clashes with reverse accessor for 'RemoshinDoctor.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'RemoshinUser.user_permissions' or 'RemoshinDoctor.user_permissions'.
remoshin_manager_sys.RemoshinUser.user_permissions: (fields.E304) Reverse accessor for 'RemoshinUser.user_permissions' clashes with reverse accessor for 'RemoshinManager.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'RemoshinUser.user_permissions' or 'RemoshinManager.user_permissions'.

I could get a lot of information about this error. But it seems there are not in my case.

I have 3 projects and each of them have different custom user model. And I use one database from 3 projects each of them have their own custom user model.

remoshin_user_sys/RemoshinUser

remoshin_clinic_sys/RemoshinDoctor

remoshin_manager_sys/RemoshinManager

This error happened when I try to run makemigrations from remoshin_manager_sys. I don't want to setup RemoshinDoctor and RemoshinUser as custom user model of RemoshinManager.

My settings.py is the following.

AUTH_USER_MODEL = 'remoshin_manager_sys.RemoshinManager'

How can I avoid this error?

Add my models.py.

class RemoshinUserManager(BaseUserManager):
    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
        now = timezone.now()

        if not email:
            raise ValueError('User must have a e-mail address.')

        email = self.normalize_email(email)

        user = self.model(email=email,
            is_staff=is_staff, is_active=True,
            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, **extra_fields):
        return self.create_user(email, password, False, False, **extra_fields)

    def create_superuser(self, email, password):
        return self.create_user(user_email, password, True, True, **extra_fields)

    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)

class RemoshinUser(AbstractBaseUser, PermissionsMixin):
    email = models.CharField(max_length=128, primary_key=True)
    username = models.CharField(max_length=64)
    user_kana_name = models.CharField(max_length=32, blank=True)
    password = models.CharField(max_length=128)
    user_birthdate = models.DateField(null=True, blank=True)
    user_sex = models.SmallIntegerField(null=True)
    user_postno = models.CharField(max_length=7, blank=True)
    user_address1 = models.CharField(max_length=128)
    user_address2 = models.CharField(max_length=128, blank=True)
    user_telno = models.CharField(max_length=16, blank=True)
    user_photo = models.ImageField(blank=True)
    authentication_status = models.BooleanField(default=False)
    create_date = models.DateTimeField(auto_now_add=True)
    modify_date = models.DateTimeField(auto_now=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['user_name', 'user_telno']

    objects = RemoshinUserManager()

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        db_table = 'remosys_remoshin_user_tbl'

    def get_absolute_url(self):
        return "/users/%s" % urlquote(self.email)


    def email_user(self, subject, message, from_email=None):
        send_mail(subject, message, from_email, [self_email])








class RemoshinDoctorManager(BaseUserManager):
    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
        now = timezone.now()

        if not email:
            raise ValueError('Doctor must have a e-mail address.')

        email = self.normalize_email(email)

        doctor = self.model(email=email,
            is_staff=is_staff, is_active=True,
            is_superuser=is_superuser, last_login=now,
            date_joined=now, **extra_fields)

        doctor.set_password(password)

        doctor.save(using=self._db)

        return doctor

    def create_user(self, email, password, **extra_fields):
        return self.create_user(email, password, False, False, **extra_fields)

    def create_superuser(self, email, password):
        return self.create_user(email, password, True, True, **extra_fields)

    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)


class RemoshinDoctor(AbstractBaseUser, PermissionsMixin):
    doctor_id = models.CharField(max_length=16, primary_key=True)
    clinic_id = models.ForeignKey(Clinic)
    email = models.CharField(max_length=128)
    password = models.CharField(max_length=128)
    username = username = models.CharField(max_length=64)
    doctor_photo = models.ImageField(blank=True, null=True)
    create_date = models.DateTimeField(auto_now_add=True)
    modify_date = models.DateTimeField(auto_now=True)

    USERNAME_FIELD = 'doctor_id'
    REQUIRED_FIELDS = ['clinic_id', 'email', 'password', 'username']

    objects = RemoshinDoctorManager()

    class Meta:
        verbose_name = _('doctor')
        verbose_name_plural = _('doctors')
        db_table = 'remosys_remoshin_doctor_tbl'

    def get_absolute_url(self):
        return "/doctors/%s" % urlquote(self.doctor_id)



class RemoshinManagerManager(BaseUserManager):
    def _create_user(self, username, email, password, is_staff, is_admin, **extra_fields):
        now = timezone.now()

        if not email:
            raise ValueError('Manager must have a e-mail address.')

        email = self.normalize_email(email)

        manager = self.model(username=username, email=email,
            is_active=True,
            is_superuser=is_admin,
            is_staff=is_staff,
            create_date=now,
            modify_date=now, **extra_fields)

        manager.set_password(password)

        manager.save(using=self._dåb)

        return manager

    def create_user(self, username, email, password, **extra_fields):
        return self._create_user(username, email, password, False, False, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        return self._create_user(username, email, password, True, True, **extra_fields)


    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)



class RemoshinManager(AbstractBaseUser, PermissionsMixin):
    manager_id = models.CharField(max_length=16, primary_key=True)
    email = models.CharField(max_length=128)
    password = models.CharField(max_length=128)
    username = models.CharField(max_length=64)

    is_active   = models.BooleanField(default=True)
    is_admin    = models.BooleanField(default=False)
    is_staff    = models.BooleanField(default=False)

    create_date = models.DateTimeField(default=timezone.now)
    modify_date = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    objects = RemoshinManagerManager()

    class Meta:
        verbose_name = _('manager')
        verbose_name_plural = _('managers')
        db_table = 'remosys_remoshin_manager_tbl'

    def get_absolute_url(self):
        return "/managers/%s" % urlquote(self.manager_id)

    def email_user(self, subject, message, from_email=None):
        send_mail(subject, message, from_email, [self.email])

    def user_has_perm(username, perm, obj):
        A backend can raise `PermissionDenied` to short-circuit permission checking.
        return _user_has_perm(username, perm, obj)

    def has_perm(self, perm, obj=None):
        return _user_has_perm(self, perm, obj=obj)

    def has_module_perms(self, app_label):
        return self.is_superuser

    def get_short_name(self):
        return self.first_name

    @property
    def is_superuser(self):
        return self.is_admin




class Consultation(models.Model):
    consultation_id = models.CharField(max_length=8, primary_key=True)
    user_email = models.ForeignKey(RemoshinUser)
    clinic_id = models.ForeignKey(Clinic)
    doctor_id = models.ForeignKey(RemoshinDoctor)
    consultation_datetime = models.DateTimeField(auto_now=True)
    consultation_status = models.BooleanField(default=False)
    prescription = models.TextField(blank=True)
    prescription_status = models.SmallIntegerField(default=0)
    payment_status = models.SmallIntegerField(default=0)
    create_date = models.DateTimeField(auto_now_add=True)
    modify_date = models.DateTimeField(auto_now=True)


    class Meta:
        db_table = 'remosys_consultation_tbl'
        # swappable = 'settings.AUTH_USER_MODEL'

I'll explain the error with an example:

Supose you have these two models.

class Book(Models.model):
    title = models.CharField(maxlength = 100)

class Person(Models.model):
    name = models.CharField(max_length = 100)
    own_book = models.ForeignKey('Book')

Simple models, but the tricky part is that Django builds reverse references whenever you define a foreign key: If person is a query object, foward reference to the title of the book she owns would be: person.own_book.title .

Now, if you want to know persons names that own a particular book? Django builds the reverse relationship, which takes the model name by default. That is, 'book' being a queryset object, you can find the names of persons that owns the book with book.person.name . Cool, right? It looks through your foreign key.

Now, add another foreign key to the same book model:

class Person(Models.model):
    name = models.CharField(max_length = 100)
    wrote_book = models.ForeignKey('Book')
    own_book = models.ForeignKey('Book')

Your foward relationships are still well defined: person.wrote_book.title and person.own_book.title . But what book.person.name is suposed to do? Look for names of persons that owns the book? that have written the book? or both? There django just throws your Reverse acessor error .

How to fix it? Djangos tells you to create a related_name in your model:

class Person(Models.model):
    name = models.CharField(max_length = 100)
    wrote_book = models.ForeignKey('Book', related_name = 'wrote')
    own_book = models.ForeignKey('Book', related_name = 'own')

So book.person.name does not exists anymore (default is overwritten) and it is replaced by book.own.name and book.wrote.name .

So my guess is: look for foreign keys defined in groups and user_permissions models and put related_names parameters on them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM