Relation Many-to-many / inspectdb
Bonjour,
M'essayant avec joie (quelques fois) à Django, je bute cependant sur quelques soucis :
J'ai une BD existante (structure à ne pas modifier donc) toute "bête" :
- une table "tbPesticide" de laquelle héritent (dans le diagramme UML hein :p) des tables "tbHerbicide", "tbInsecticide", "tbFongicide" et "tbAutres"
- une table "tbExploitant"
- une table "Utilisation" liant ces deux dernières (typiquement pour savoir quels pesticides sont utilisés par certains exploitants)
Voici donc le script de création pour MySQL :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| --
-- Base de données: `pesticides`
--
-- --------------------------------------------------------
--
-- Structure de la table `tbAutres`
--
CREATE TABLE IF NOT EXISTS `tbAutres` (
`IdPesticide` int(11) NOT NULL,
PRIMARY KEY (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `tbExploitant`
--
CREATE TABLE IF NOT EXISTS `tbExploitant` (
`Nom` varchar(255) default NULL,
`IdExploitant` int(11) NOT NULL auto_increment,
PRIMARY KEY (`IdExploitant`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `tbFongicide`
--
CREATE TABLE IF NOT EXISTS `tbFongicide` (
`IdPesticide` int(11) NOT NULL,
PRIMARY KEY (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `tbHerbicide`
--
CREATE TABLE IF NOT EXISTS `tbHerbicide` (
`IdPesticide` int(11) NOT NULL,
PRIMARY KEY (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `tbInsecticide`
--
CREATE TABLE IF NOT EXISTS `tbInsecticide` (
`IdPesticide` int(11) NOT NULL,
PRIMARY KEY (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `tbPesticide`
--
CREATE TABLE IF NOT EXISTS `tbPesticide` (
`Nom` varchar(255) default NULL,
`IdPesticide` int(11) NOT NULL auto_increment,
PRIMARY KEY (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `Utilisation`
--
CREATE TABLE IF NOT EXISTS `Utilisation` (
`IdExploitant` int(11) NOT NULL,
`IdPesticide` int(11) NOT NULL,
PRIMARY KEY (`IdExploitant`,`IdPesticide`),
KEY `Pesticide_of_Utilisation_FK` (`IdPesticide`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Contraintes pour les tables exportées
--
--
-- Contraintes pour la table `tbAutres`
--
ALTER TABLE `tbAutres`
ADD CONSTRAINT `tbPesticide_of_tbAutres_FK` FOREIGN KEY (`IdPesticide`) REFERENCES `tbPesticide` (`IdPesticide`);
--
-- Contraintes pour la table `tbFongicide`
--
ALTER TABLE `tbFongicide`
ADD CONSTRAINT `tbPesticide_of_tbFongicide_FK` FOREIGN KEY (`IdPesticide`) REFERENCES `tbPesticide` (`IdPesticide`);
--
-- Contraintes pour la table `tbHerbicide`
--
ALTER TABLE `tbHerbicide`
ADD CONSTRAINT `tbPesticide_of_tbHerbicide_FK` FOREIGN KEY (`IdPesticide`) REFERENCES `tbPesticide` (`IdPesticide`);
--
-- Contraintes pour la table `tbInsecticide`
--
ALTER TABLE `tbInsecticide`
ADD CONSTRAINT `tbPesticide_of_tbInsecticid_FK` FOREIGN KEY (`IdPesticide`) REFERENCES `tbPesticide` (`IdPesticide`);
--
-- Contraintes pour la table `Utilisation`
--
ALTER TABLE `Utilisation`
ADD CONSTRAINT `Agriculteur_of_Utilisation_FK` FOREIGN KEY (`IdExploitant`) REFERENCES `tbExploitant` (`IdExploitant`),
ADD CONSTRAINT `Pesticide_of_Utilisation_FK` FOREIGN KEY (`IdPesticide`) REFERENCES `tbPesticide` (`IdPesticide`); |
J'ai donc utilisé "python manage.pf inspectdb" pour avoir une base de modèles.
Après modification de celle-ci, j'arrive donc à ça :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| from django.db import models
### Pesticide ###
class Pesticide(models.Model):
nom = models.CharField(max_length=765, db_column='Nom', blank=True)
idpesticide = models.AutoField(primary_key=True, db_column='IdPesticide')
def __str__(self) :
return self.nom
class Meta:
db_table = 'tbPesticide'
### Autre ###
class Autre(Pesticide):
idPesticide = models.OneToOneField(Pesticide, parent_link = True, db_column='idPesticide')
class Admin :
pass
class Meta:
db_table = 'tbAutres'
### Fongicide ###
class Fongicide(Pesticide):
idPesticide = models.OneToOneField(Pesticide, parent_link = True, db_column='idPesticide')
class Meta:
db_table = 'tbFongicide'
class Admin :
pass
### Herbicide ###
class Herbicide(Pesticide):
idPesticide = models.OneToOneField(Pesticide, parent_link = True, db_column='idPesticide')
class Admin :
pass
class Meta:
db_table = 'tbHerbicide'
### Insecticide ###
class Insecticide(Pesticide):
idPesticide = models.OneToOneField(Pesticide, parent_link = True, db_column='idPesticide')
class Meta:
db_table = 'tbInsecticide'
ordering = ['nom']
class Admin :
pass
### Exploitant ###
class Exploitant(models.Model):
nom = models.CharField(max_length=765, db_column='Nom', blank=True)
idexploitant = models.AutoField(primary_key=True, db_column='IdExploitant')
pesticides = models.ManyToManyField(Pesticide, through='Utilisation')
class Meta:
db_table = 'tbExploitant'
### Utilisation ###
class Utilisation(models.Model):
exploitant = models.ForeignKey(Exploitant, db_column='IdExploitant', primary_key=True)
pesticide = models.ForeignKey(Pesticide, db_column='IdPesticide', primary_key=True)
class Meta:
db_table = 'Utilisation' |
Et pourtant, dans mon interface de création d'exploitant, la liste des pesticides existant n'apparaît pas, malgré mon acharnement, je n'ai pas réussi à, à la fois, afficher ceux-ci ET ne pas avoir d'erreur lors de la création car il me renvoyait souvent un problème de nom de table intermediaire.
Citation:
Exception Value:
(1146, "Table 'pesticides.tbExploitant_pesticides' doesn't exist")
Donc je commence à désespérer (d'autant plus que la gestion des liens d'héritages n'est pas aussi bien gérée dans d'autres outils du genre). Si vous avez une idée ou besoin d'informations complémentaires, faites m'en part.
Merci d'avance ;)
Edit : Je viens d'essayer d'utiliser db_table :
Code:
pesticides = models.ManyToManyField(Pesticide, db_table='Utilisation')
Et en retour, je reçois, entre autres :
Citation:
(1054, "Unknown column 'Utilisation.exploitant_id' in 'where clause'")
Il faudrait que je puisse spécifier quel champ est la clé étrangère vers mon exploitant ... (ce qui est pourtant défini via mes contraintes).
Edit 2 : Apparement, Django n'accepte pas les clés primaires multiples :
Citation:
"Each model requires exactly one field to have primary_key=True."
N'étant pas disposé à rajouter un champ id à ma table 'Utilisation', que puis-je faire ?