Django-fr

Forum

#1 07-05-2012 13:48:12

dseed
Membre
Inscription : 21-09-2011
Messages : 7

Models auto-increment clé unique

Bonjour,

J'aimerais crée en DJANGO un id auto-incrementé en clé UNIQUE car ma "veritable" clé primaire est un varchar (et par conséquent vu que d'autres table ont des clé étrangère je prefere que ces clé se fasse sur un id et non sur un varchar)

J'ai réussit en requête MySql mais avec Django quand je créé un id auto increment avec comme param unique=true il me génère une erreur me disant qu'il faut qu'une valeur auto-incrementé soit une clé primaire !

Donc est ce vous savez comment faire pour créé un id auto-incrementé en clé unique ?

Merci de votre aide.

Hors ligne

#2 07-05-2012 14:20:08

dseed
Membre
Inscription : 21-09-2011
Messages : 7

Re : Models auto-increment clé unique

Voila ce que j'aimerais :
id_url = models.AutoField(unique=True)
url = models.CharField(max_length=255, primary_key=True)

PS: j'ai fait une synchro : python manage.py inspectdb > models.py
Mysql vers mon models et j'ai ça :

id_url = models.IntegerField(unique=True)
url = models.CharField(max_length=255, primary_key=True)

Mais mon id_url n'est pas auto incrementé pourtant sur Mysql si on dirait que Dajngo ne prend pas en compre l'auto increment de la table Mysql ... ?

Hors ligne

#3 07-05-2012 15:01:53

David Thenon
Membre
Inscription : 11-08-2010
Messages : 156
Site Web

Re : Models auto-increment clé unique

Salut,

L'attribut 'primary_key' n'est vraiment utile à mon sens qu'avec un
'AutoField', mais en tout cas je doute fortement qu'il soit utile sur un
CharField (comme dans ton exemple) qui implique un string qu'on ne peut pas
incrémenter.

Et vu que c'est id_url que tu veux incrémenter, c'est donc sur lui que tu dois
ajouter l'option du primary_key :

  id_url = models.AutoField(unique=True, primary_key=True)
  url = models.CharField(max_length=255)

Cela dit, le schéma de ta table sql doit le prévoir, vu que l'auto-increment
se fait au niveau de la bdd, pas de Django.

Hors ligne

#4 07-05-2012 15:15:20

Rémy HUBSCHER
Membre
Inscription : 11-08-2010
Messages : 161

Re : Models auto-increment clé unique

Primary_key veut dire que le champ peut être utilisé pour identifier de
manière sûre l'instance de l'objet. (ou la ligne dans le dbm)

ça à du sens sur un charfield qui sera donc unique.

Par défaut Django créé un Autofield qui va être auto-incrémenté mais il
est possible de changer cela avec l'attribut primary_key.
Le fait que ce soit une primary_key ne veut pas dire que ce sera
auto-incrémenté mais que ce sera l'identifiant de l'instance.

mes 2 cents.

Le lun. 07 mai 2012 16:01:53 CEST, David THENON a écrit :
> Salut,
>
> L'attribut 'primary_key' n'est vraiment utile à mon sens qu'avec un
> 'AutoField', mais en tout cas je doute fortement qu'il soit utile sur un
> CharField (comme dans ton exemple) qui implique un string qu'on ne peut pas
> incrémenter.
>
> Et vu que c'est id_url que tu veux incrémenter, c'est donc sur lui que tu dois
> ajouter l'option du primary_key :
>
>    id_url = models.AutoField(unique=True, primary_key=True)
>    url = models.CharField(max_length=255)
>
> Cela dit, le schéma de ta table sql doit le prévoir, vu que l'auto-increment
> se fait au niveau de la bdd, pas de Django.
>

Hors ligne

#5 07-05-2012 15:16:26

Rémy HUBSCHER
Membre
Inscription : 11-08-2010
Messages : 161

Re : Models auto-increment clé unique

Le 07/05/2012 16:01, David THENON a écrit :
> Salut,
>
> L'attribut 'primary_key' n'est vraiment utile à mon sens qu'avec un
> 'AutoField', mais en tout cas je doute fortement qu'il soit utile sur un
> CharField (comme dans ton exemple) qui implique un string qu'on ne peut pas
> incrémenter.
>
> Et vu que c'est id_url que tu veux incrémenter, c'est donc sur lui que tu dois
> ajouter l'option du primary_key :
>
>    id_url = models.AutoField(unique=True, primary_key=True)
>    url = models.CharField(max_length=255)
>
> Cela dit, le schéma de ta table sql doit le prévoir, vu que l'auto-increment
> se fait au niveau de la bdd, pas de Django.
>
Ceci dit, effectivement si tu as un id_url AutoField, il vaut mieux
faire comme cela :

   id_url = models.AutoField(primary_key=True)
   url = models.CharField(max_length=255, unique=True)

Hors ligne

#6 07-05-2012 15:16:59

Rémy HUBSCHER
Membre
Inscription : 11-08-2010
Messages : 161

Re : Models auto-increment clé unique

Le 07/05/2012 16:01, David THENON a écrit :
> Salut,
>
> L'attribut 'primary_key' n'est vraiment utile à mon sens qu'avec un
> 'AutoField', mais en tout cas je doute fortement qu'il soit utile sur un
> CharField (comme dans ton exemple) qui implique un string qu'on ne peut pas
> incrémenter.
>
> Et vu que c'est id_url que tu veux incrémenter, c'est donc sur lui que tu dois
> ajouter l'option du primary_key :
>
>    id_url = models.AutoField(unique=True, primary_key=True)
>    url = models.CharField(max_length=255)
>
> Cela dit, le schéma de ta table sql doit le prévoir, vu que l'auto-increment
> se fait au niveau de la bdd, pas de Django.
>
Voire même :

   id_url = models.AutoField(primary_key=True)
   url = models.URLField(max_length=255, unique=True)

Hors ligne

#7 07-05-2012 15:32:18

dseed
Membre
Inscription : 21-09-2011
Messages : 7

Re : Models auto-increment clé unique

Oui c'est vrais Rémy c'est une bonne idée ça revient au même si je met l'url en unique ou l'id c'est pareil autant respecté les normes et mettre l'id auto incrementé en primary key

Hors ligne

#8 07-05-2012 15:40:53

dseed
Membre
Inscription : 21-09-2011
Messages : 7

Re : Models auto-increment clé unique

Mais pour  une table de croisement j'ai réussit mettre 2 champs en clé etrangère qui sont des clé primaires : PRIMARY KEY (`id_url`,`id_user`)
ps:  ca fonctionne !!
Comment je fais en Django pour retranscrire ça ?

CREATE TABLE `t_x_site` (
  `id_x_site` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_user` int(11) unsigned NOT NULL,
  `id_url` int(11) unsigned NOT NULL,
  `nb_visite` int(11) unsigned NOT NULL DEFAULT '0',
  `date_visite` datetime DEFAULT NULL,
  `recommander` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `actif` tinyint(1) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id_url`,`id_user`),
  UNIQUE KEY `id_x_site` (`id_x_site`),
  KEY `lien_url` (`id_url`),
  KEY `lien_user` (`id_user`),
  CONSTRAINT `lien_url` FOREIGN KEY (`id_url`) REFERENCES `t_url` (`id_url`),
  CONSTRAINT `lien_user` FOREIGN KEY (`id_user`) REFERENCES `t_user` (`id_user`)
) ENGINE=InnoDB AUTO_INCREMENT=549 DEFAULT CHARSET=utf8;

Hors ligne

#9 07-05-2012 16:04:15

Rémy HUBSCHER
Membre
Inscription : 11-08-2010
Messages : 161

Re : Models auto-increment clé unique

Tu ne peux pas faire une primary_key dessus par contre tu peux
configurer un UNIQUE TOGETHER.

Le lun. 07 mai 2012 16:40:53 CEST, dseed a écrit :
>
> Mais pour une table de croisement j'ai réussit mettre 2 champs en clé
> etrangère qui sont des clé primaires : PRIMARY KEY (`id_url`,`id_user`)
> ps: ca fonctionne !!
> Comment je fais en Django pour retranscrire ça ?
>
> CREATE TABLE `t_x_site` (
> `id_x_site` int(11) unsigned NOT NULL AUTO_INCREMENT,
> `id_user` int(11) unsigned NOT NULL,
> `id_url` int(11) unsigned NOT NULL,
> `nb_visite` int(11) unsigned NOT NULL DEFAULT '0',
> `date_visite` datetime DEFAULT NULL,
> `recommander` tinyint(1) unsigned NOT NULL DEFAULT '0',
> `actif` tinyint(1) unsigned NOT NULL DEFAULT '0',
> PRIMARY KEY (`id_url`,`id_user`),
> UNIQUE KEY `id_x_site` (`id_x_site`),
> KEY `lien_url` (`id_url`),
> KEY `lien_user` (`id_user`),
> CONSTRAINT `lien_url` FOREIGN KEY (`id_url`) REFERENCES `t_url`
> (`id_url`),
> CONSTRAINT `lien_user` FOREIGN KEY (`id_user`) REFERENCES `t_user`
> (`id_user`)
> ) ENGINE=InnoDB AUTO_INCREMENT=549 DEFAULT CHARSET=utf8;
> _______________________________________________
> django mailing list
> django _AT_ lists.afpy.org
> http://lists.afpy.org/mailman/listinfo/django

Hors ligne

#10 07-05-2012 16:05:39

dseed
Membre
Inscription : 21-09-2011
Messages : 7

Re : Models auto-increment clé unique

j'ai trouvé :

class Meta:
        unique_together = ("id_user", "id_url")

:-)

Hors ligne

#11 07-05-2012 16:08:18

Chamal
Membre
Inscription : 11-08-2010
Messages : 17

Re : Models auto-increment clé unique

Le 7 mai 2012 à 16:40, dseed a écrit :

> Mais pour  une table de croisement j'ai réussit mettre 2 champs en clé
> etrangère qui sont des clé primaires : PRIMARY KEY (`id_url`,`id_user`)
> ps:  ca fonctionne !!
> Comment je fais en Django pour retranscrire ça ?
>
> CREATE TABLE `t_x_site` (
>  `id_x_site` int(11) unsigned NOT NULL AUTO_INCREMENT,
>  `id_user` int(11) unsigned NOT NULL,
>  `id_url` int(11) unsigned NOT NULL,
>  `nb_visite` int(11) unsigned NOT NULL DEFAULT '0',
>  `date_visite` datetime DEFAULT NULL,
>  `recommander` tinyint(1) unsigned NOT NULL DEFAULT '0',
>  `actif` tinyint(1) unsigned NOT NULL DEFAULT '0',
>  PRIMARY KEY (`id_url`,`id_user`),
>  UNIQUE KEY `id_x_site` (`id_x_site`),
>  KEY `lien_url` (`id_url`),
>  KEY `lien_user` (`id_user`),
>  CONSTRAINT `lien_url` FOREIGN KEY (`id_url`) REFERENCES `t_url`
> (`id_url`),
>  CONSTRAINT `lien_user` FOREIGN KEY (`id_user`) REFERENCES `t_user`
> (`id_user`)
> ) ENGINE=InnoDB AUTO_INCREMENT=549 DEFAULT CHARSET=utf8;


De manière générale lorsque une table de croisement comporte des attributs
qui lui sont propres (et non pas uniquement le couple id_table1, id_table2)
il est préférable de rajouter une primary key a cette table, plutôt que
d'utiliser id_table1 + id_table2 en tant que tel.

De plus en django il y a une limitation qui fait que nous ne pouvons pas avoir
une primary key sur plusieurs champs (cf https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys)

Je te conseille donc de déclarer id_x_site en primary key et de mettre
une contrainte d'unicité sur id_url + id_user et cela devrait moins poser de
souci dans ton appli.

Hors ligne

Pied de page des forums