Django e problema de remendos de macacos
-
22-09-2019 - |
Pergunta
Recentemente, comecei a experimentar o Django para alguns aplicativos da Web no meu tempo livre. Ao projetar o modelo de dados para um, me deparei com o dilema do uso da herança para definir um usuário do site ou usar uma técnica conhecida como patch de macaco com a classe de usuário já fornecida pela estrutura.
Tentei adicionar um campo por meio (depois de definir todos os meus modelos etc. sem erros, de acordo com python manage.py validate
):
User.add_to_class('location', models.CharField(max_length=250,blank=True))
e executou o syncdb
comando. No entanto, continuo recebendo este erro
OperationalError: Nenhuma coluna: auth_user.Location
Se estou na visão de administrador do site ou no shell gerenciador.py. Deve haver uma etapa extra que estou perdendo, mas parece haver documentação limitada em toda a técnica de patch de macaco. Então, estou pedindo ajuda antes de recorrer à herança. Qualquer código, dicas ou indicadores de documentação adicional é obviamente bem -vindo.
Desde já, obrigado.
Ps. Estou ciente de que essa técnica é feia e provavelmente mal recomendada. ;)
Solução
Quando você adiciona um campo a qualquer modelo, mesmo se você o fizer da maneira 'oficial', precisa migrar o banco de dados - o Django não faz isso por você. Solte a mesa e corra ./manage.py syncdb
novamente.
Você pode querer investigar uma das estruturas de migrações, como south
, que gerenciará esse tipo de coisa para você.
Outras dicas
Há uma alternativa para ambas as abordagens, que é simplesmente usar um modelo de perfil relacionado. Isso também é uma abordagem bem documentada e altamente recomendada. Talvez a razão pela qual a abordagem add_to_class não esteja bem documentada, como você observou, é porque é explicitamente desencorajado (por uma boa razão).
Aqui está um (um pouco mais antiga) maneira de estender o User
modelo.
Aqui está O que os documentos têm a dizer.
E aqui está um conversas recentes sobre usuários de django sobre o tópico.
O Djangos Framework usa metaclasses para inicializar as tabelas. Isso significa que você não pode ser um patch de macaco em novas colunas, a menos que você também reinicialize a classe, o que não tenho certeza se é possível. (Pode ser).
Ver Diferença entre a classe modificada de retorno e o uso do tipo () Para mais algumas informações.
Eu acho que você pode ter problemas sobre onde está o seu Monkeypatch definido. Eu acho que o Django SyncDB cria tabelas de banco de dados apenas do aplicativo de autenticação "Pure", para que seu modelo ficará sem "localização" e, em seguida, seu site com o patch procurará o campo.
Provavelmente uma maneira menos dolorosa de adicionar informações adicionais aos perfis de usuário é descrita em Django Docs.