2017-10-21 11 views
1

Je suis en train de créer un modèle pour le scénario suivant:modèles Django - créer des éléments qui doivent passer différentes tâches

Un élément est livré et doit passer par diverses tâches dans un certain ordre. Dès que l'élément a passé une tâche, la tâche est marquée comme terminée. Les noms des tâches sont connus à l'avance.

Par exemple:

  • Créer un élément
  • tâche 1 'inscrire l'élément'
  • Tâche 2 'installer l'élément'
  • Tâche 3 'vérifier les journaux de l'article'

J'ai commencé avec un modèle simple comme celui-ci, b J'ai l'air très statique et pas vraiment ce que je cherche.

models.py

class Item(models.Model): 

    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 

    task1_name = models.CharField(max_length=128) 
    task1_done_by = models.CharField(max_length=64, blank=True) 
    task1_done_date = models.DateField(null=True, blank=True) 

    task2_name = models.CharField(max_length=128) 
    task2_done_by = models.CharField(max_length=64, blank=True) 
    task2_done_date = models.DateField(null=True, blank=True) 

    # ... next 20 tasks 

    def __str__(self): 
     return str(self.item_id) 

Essayer des champs relationnels, par exemple un ManyToMany terrain pour pré définir les tâches, j'ai fini avec ceci:

class Task(models.Model): 

    name = models.CharField(max_length=128) 
    done_by = models.CharField(max_length=64, blank=True) 
    done_date = models.DateField(null=True, blank=True) 


class Item(models.Model): 

    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 
    tasks = models.ManyToManyField(Task) 

Mais, si je crée deux éléments avec les mêmes tâches et marquer la tâche du premier élément comme fait il sera marqué comme fait dans le deuxième article aussi - ce n'est pas ce que je veux.

Comment affecter une tâche à un élément spécifique? Ou quel autre modèle conviendrait le mieux à mon scénario?

Répondre

1

Pour l'exécution du code au moment de la création de l'objet, vous remplacez généralement la méthode save(). Alors, quand un élément est créé, dans la méthode save vous créez et lier dynamiquement les tâches à Item.tasks

class Item(models.Model): 
    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 

    # remove m2m !!! 

    def save(self, *args, **kwargs): 
     # If it has no pk then it is a *new* item 
     if not self.pk: 

      # Save by manually 
      # Call save of parent class (models.Model) creating the custom class 
      super(Item, self).save(*args, **kwargs) 

      # Now you have the PK 
      t1 = Task(name='T1', item=self) 
      t1.save() 
      #... 

class Task(models.Model): 
    name = models.CharField(max_length=128) 
    done_by = models.CharField(max_length=64, blank=True) 
    done_date = models.DateField(null=True, blank=True) 

    # Add Item FK 
    item = models.ForeignKey(Item) 

Remarque sur le code de mise à jour():

1) J'ai changé la direction: les liens de travail à l'article, pas l'inverse. Voir https://docs.djangoproject.com/en/1.11/topics/db/examples/many_to_one/

2) Je vérifie toujours s'il s'agit d'une nouvelle instance, puis j'appelle super save puis je crée la tâche pour cet item.

Assurez-vous de vérifier la valeur self.pk sinon le code sera exécuté également lors de la mise à jour de l'objet.

Sachez également que vous devez créer un nouvel objet Task lié à un objet Item à chaque fois. Si vous liez un objet de tâche à deux éléments, lorsque item_a termine une tâche, la tâche semble également terminée pour item_b.

Ce que vous devez faire est de créer task1 pour item_a et task2 pour item_b. De cette façon, vous séparez les tâches.

Lire la suite:

https://docs.djangoproject.com/en/1.11/ref/models/instances/#saving-objects

https://docs.djangoproject.com/en/1.11/topics/db/models/#relationships

+0

J'ai réglé ma question un peu pour clarifier mon problème: si je crée deux articles avec les mêmes tâches et marquer la tâche du premier élément comme fait, il sera marqué comme fait dans le deuxième article aussi - ce n'est pas ce que je veux et je cherche une solution à cela. –

+1

L'élément class (models.Models) est un modèle pour un objet de base de données. Vous créez des instances à partir de celui-ci. Si vous liez une instance de tâche à deux instances d'élément et mettez à jour la tâche, il en sera de même pour les deux éléments qui s'y rattachent. Ce que vous devez faire est de créer task1 pour item1 et task2 pour item2. De cette façon, vous séparez les tâches. – rollinger

+0

Je commence à comprendre. Je dois créer et lier de nouvelles tâches à chaque nouvel élément et je ne peux pas les réutiliser. Avez-vous un exemple de code pour créer et ajouter une tâche à la main? –