0

I'm trying to customize the authentication that comes by default in Django with a table of Mysql already made (collaborators). When I want to register a user (with the command python manage.py createsuperuser) I get the following error:

django.db.utils.OperationalError: (1054, "Unknown column 'collaborators.password' in 'field list'").

That error mentions that the password column does not exist, and indeed I do not have it in the table, is there any way to indicate that the password is obtained from a column called contrasena_general? I attach my code.

models.py

class MyUserManager(BaseUserManager):
    use_in_migrations = True

    def create_superuser(self, no_colaborador, nombres_colaborador, apellido_paterno_colaborador, apellido_materno_colaborador,
                        id_plantel, id_area_colaborador, no_empleado_sup, contrasena_general, empleado_interno):

        user = self.model(no_colaborador = no_colaborador, nombres_colaborador = nombres_colaborador, 
            apellido_paterno_colaborador = apellido_paterno_colaborador, apellido_materno_colaborador = apellido_materno_colaborador,
            id_plantel = id_plantel, id_area_colaborador = id_area_colaborador, no_empleado_sup = no_empleado_sup, 
            contrasena_general = contrasena_general, empleado_interno = empleado_interno,)
        user.set_password(contrasena_general)
        user.save(using=self._db)
        return user

class Colaboradores(AbstractBaseUser):
    no_colaborador = models.IntegerField(primary_key=True)
    nombres_colaborador = models.CharField(max_length=150)
    apellido_paterno_colaborador = models.CharField(max_length=150)
    apellido_materno_colaborador = models.CharField(max_length=150)
    id_plantel = models.IntegerField()
    id_area_colaborador = models.IntegerField()
    id_centro_costos = models.IntegerField()
    no_empleado_sup = models.IntegerField()
    contrasena_general = models.CharField(max_length=100)
    empleado_interno = models.CharField(max_length=10)

    objects = MyUserManager()

    USERNAME_FIELD = "no_colaborador"

    class Meta:
        managed = False
        db_table = 'collaborators'
        app_label = "journal"

    def __str__ (self): 
        return self.email 

    def def_full_name (self): 
        return self.nombres_colaborador

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

    def has_module_perms(self, app_label):
        return self.no_colaborador
# backends.py

class MyAuthBackend(object):
    def authenticate(self, no_colaborador, contrasena_general):    
        try:
            user = Colaboradores.objects.get(no_colaborador=no_colaborador)
            if user.check_password(contrasena_general):
                return user
            else:
                return None
        except Colaboradores.DoesNotExist:
            logging.getLogger("error_logger").error("user with login %s does not exists " % login)
            return None
        except Exception as e:
            logging.getLogger("error_logger").error(repr(e))
            return None

    def get_user(self, no_colaborador):
        try:
            user = Colaboradores.objects.get(no_colaborador=no_colaborador)
            if user.is_active:
                return user
            return None
        except Colaboradores.DoesNotExist:
            logging.getLogger("error_logger").error("user with %(no_colaborador)d not found")
            return None
# setting.py
...
AUTH_USER_MODEL = 'journal.Colaboradores'
AUTHENTICATION_BACKENDS = ('clientes.backends.MyAuthBackend', 'django.contrib.auth.backends.ModelBackend',)

How could you indicate that the password is obtained from a column in the table that is not called a password?

ilja
  • 2,592
  • 2
  • 16
  • 23
CJovany
  • 1
  • 1

1 Answers1

0

I think creating your own createsuperuser command would solve this issue.

Ref: Is it possible to make my own createsuperuser command in django?

You can make your based on the the original source code for Django's createsuperuser that can be found on Github.

As you can see from there, there is a constant on line 20 that says:

PASSWORD_FIELD = 'password'

So I guess that since you changed it in the model to contrasena_general, you need to make your own custom command.

caiolopes
  • 561
  • 8
  • 14
  • Thank you for your answer, but even with `PASWORD_FIELD = "contrasena_general"` does not work, it keeps generating the same error. – CJovany May 08 '19 at 14:09
  • Are you sure there is no typo? You wrote `PASWORD_FIELD` and not `PASSWORD_FIELD` (just to make sure). – caiolopes May 08 '19 at 19:15