2010-08-10 4 views
1

Je suis en train de développer une application interne pour l'entreprise pour laquelle je travaille, et je veux utiliser Django pour l'apprendre et Python en général, mais j'ai rencontré un peu de un accroc avec les PK. J'essaie d'émuler une partie de l'application actuelle où 2 tables MySQL, TaskCategory et Tasks, gèrent les tâches à effectuer. Chaque tâche appartient à une TaskCategory et chaque élément de TaskCategory a son propre numéro d'incrémentation distinct. Ainsi, si "Office" a 15 tâches, l'ajout d'une autre tâche fera son Task.taskid = 16, mais l'ajout d'une tâche à "Vehicles" fera le Tasks.taskid = 51, pas 17. Cela sera alors utilisé comme un numéro de suivi, par exemple la tâche Véhicules-51.Implémentation de clés primaires incrémentées distinctes dans Django

Cette incrémentation distincte a été réalisée en ayant une clé primaire composée dans les tâches consistant en taskcategoryid et taskid (qui s'incrémente automatiquement). D'ailleurs, Tasks.taskcategoryid n'est pas un FK (je ne pense pas qu'il puisse l'être de toute façon, car il fait partie du PK composé).

Comme Django n'aime pas plus de 1 colonne PK, j'ai eu du mal à reproduire cette fonctionnalité. J'ai essayé un unique_together de taskid (auto-incrémentant PK) et taskcategoryid (FK) et j'ai essayé d'avoir 2 colonnes à auto-incrémentation (id et taskid) mais vous ne pouvez pas avoir plus d'une colonne auto-incrémentante.

Est-il possible d'obtenir cette fonction d'incrémentation avec Django? Je préférerais le faire sans avoir à pirater le code source mais je le ferai si besoin est.

Répondre

1

Quel est votre objectif ici?

Si vous essayez de maintenir une compatibilité de table de champ à champ avec l'ancienne application, vous allez avoir des problèmes car (comme vous l'avez remarqué) Django ne fait pas compound/composite keys - il préfère vraiment surrogate key . Compte tenu des opérations autorisées par Django et de la réflexion actuelle sur la conception de bases de données «correctes», les clés de substitution ont du sens. Si tout ce que vous essayez vraiment de faire est de garder la plupart des requêtes identiques (ou similaires), alors vous pourriez laisser les champs clés naturels/composites seuls, mais abandonner l'ancienne contrainte de clé primaire, ajouter un nouvelle clé de substitution pour Django, puis ajoutez Meta data à vos modèles pour déclarer que les champs qui composent les anciennes clés composées sont unique_together. Django va interpréter cela et ajouter les index uniques appropriés. Vous aurez besoin d'ajouter du code à la création d'objet pour gérer l'incrémentation/assignation des identifiants TaskCategory, mais le résultat final est que toutes vos anciennes relations sont appliquées par Django et la base de données.

À titre d'exemple, voici une partie du modèle à partir d'une application que je mets ensemble pour suivre les joueurs dans un tournoi de jeux de société:

class Player(models.Model): 
    badge = models.IntegerField() 
    name = models.CharField(max_length = 99) 

class Round(models.Model): 
    name = models.CharField(max_length = 9) 
    number = models.IntegerField() 

class Table(models.Model): 
    round = models.ForeignKey(Round) 
    number = models.IntegerField('table number') 

    class Meta: 
     unique_together = ('round', 'number') 

class Seat(models.Model): 
    table = models.ForeignKey(Table) 
    position = models.IntegerField('seat number') 
    player = models.ForeignKey(Player) 

    class Meta: 
     unique_together = ('table', 'seat') 

Dans ce cas, j'utilise unique_together pour faire en sorte que tandis que le nombre de table sont réutilisés pour différents tours, et que les positions des sièges sont les mêmes sur toutes les tables, vous ne rencontrerez jamais la même combinaison de rond, de table et de siège plus d'une fois.

+0

Ce que j'essaie finalement de faire, c'est d'augmenter le nombre de tâches de manière incrémentielle, mais d'avoir un total différent pour chaque catégorie de tâches qui s'incrémente automatiquement pour chaque ligne ajoutée. Comme l'attribution des différents numéros de tâche est faite par MySQL, et Django ne vous permet pas de créer des clés composées, je ne pense pas que Django soit adapté à mes besoins dans ce cas. Je suppose que je vais devoir utiliser un cadre plus souple tel que Pylons pour ce projet – Mark

Questions connexes