2016-06-22 1 views
0

J'ai un modèle d'activité qui crée un objet d'activité chaque fois qu'un objet News est créé. L'objet News a ses tags.Comment copier le champ d'un objet dans le champ d'un autre objet

class Tag(models.Model): 
    slug = models.SlugField() 

class News(models.Model): 
    user = models.ForeignKey(User) 
    title = models.CharField(max_length=150) 
    tags = models.ManyToManyField(Tag) 
    activity = GenericRelation(Activity) 

class Activity(models.Model): 
    actor_type = models.ForeignKey(ContentType, related_name='actor_type_activities') 
    actor_id = models.PositiveIntegerField() 
    ... 
    ... 
    target_type = models.ForeignKey(ContentType, related_name='target_type_activities') 
    target_id = models.PositiveIntegerField() 
    target = GenericForeignKey('target_type', 'target_id') 
    tags = models.ManyToManyField(Tag) 

Maintenant, en utilisant des signaux, j'ai essayé d'obtenir l'étiquette de l'objet Nouvelles de cette façon,

@receiver(post_save, sender=News) 
def create_activity(sender, **kwargs): 
    if kwargs.get('created', False): 
     actor_type = ContentType.objects.get_for_model(kwargs.get('instance').user) 
     actor_id = kwargs.get('instance').user.id 
     target_type = ContentType.objects.get_for_model(kwargs.get('instance')) 
     target_id = kwargs.get('instance').id 
     ... 
     ... 
     # this didn't work 
     tags = kwargs.get('instance').tags.all() 
     # even this didn't work 
     tags = target_type.get_object_for_this_type(id=target_id).tags.all() 

     activity = Activity.objects.get_or_create(
      actor_type=actor_type, 
      actor_id=actor_id, 
      verb=verb, 
      target_type=target_type, 
      target_id=target_id, 
      tags=tags, 
      pub_date=pub_date 
     ) 

Mais je reçois une erreur:

'tags' is an invalid keyword argument for this function

Comment copier l'objet Nouvelles de des balises dans la liste des balises de l'objet Activity?

Répondre

0

Je pense qu'il serait beaucoup plus propre de stocker kwargs.get ('instance') dans une variable, puis de travailler avec cela. Cela permettra également de se débarrasser de votre erreur. Les étiquettes doivent ensuite être attribuées après la création de l'objet d'activité.

if kwargs.get('created', False): 
    news_obj = kwargs.get('instance') 
    if not news_obj: 
     return 
    actor_type = ContentType.objects.get_for_model(news_obj.user) 
    actor_id = news_obj.user.id 
    target_type = ContentType.objects.get_for_model(news_obj) 
    target_id = news_obj.id 
    ... 
    ... 
    tags = news_obj.tags.all() 

    activity = Activity.objects.get_or_create(
     actor_type=actor_type, 
     actor_id=actor_id, 
     verb=verb, 
     target_type=target_type, 
     target_id=target_id, 
     pub_date=pub_date 
    ) 

    activity.tags.add(*tags) 
    activity.save() 
+0

Salut. Je l'ai changé à votre façon. Maintenant, je ne reçois aucune erreur. Mais les objets d'étiquette n'attribuent pas non plus à l'objet d'activité après la création de l'activité. Pour vérifier plus loin, après le 'activity.tags.add (* tags)' j'ai ajouté cette ligne 'activity.verb =" changed "' et ensuite 'activity.save()'. Cela change. Cependant, les tags ne sont pas affectés aux activity.tags. Qu'est-ce que je rate? – Aamu

+0

Hmm, je suppose qu'il pourrait y avoir d'autres bugs. Je pense que vous devriez essayer d'imprimer des étiquettes et vérifier si elles sont vraiment là. Ensuite, vous pouvez également essayer de les ajouter un par un au lieu d'en vrac (bien que le volume soit plus rapide). Donc, vous devez remplacer activity.tags.add (* tags) par "pour t dans les balises: activity.add (t)" – steffens21

+0

Oui. Tu as raison. Pour être sûr que j'ai fait ceci 'tags = activity.target.tags.all()' et ensuite 'activity.verb ="% s "% (tags.first())'. Mais au lieu d'obtenir le premier tag, le verbe que j'ai obtenu était 'None'. – Aamu

0

Vous devriez faire attention à la retraçage que vous obtenez. Même si vous ne l'avez pas posté ici, il apparaîtra clairement que l'erreur survient lorsque vous créez l'activité, et non lorsque vous lisez l'étiquette de News. En effet, vous ne pouvez pas transmettre de données pour un champ plusieurs-à-plusieurs lorsque vous instanciez un modèle, car un objet doit être enregistré avant de pouvoir lui affecter des relations M2M.

Vous devez prendre la ligne tags de l'appel get_or_create et les affecter par la suite.

+0

Bonjour, j'ai supprimé l'affectation des tags de l'appel 'get_or_create', puis j'ai été affecté. Mais même alors les activity.tags ne sont pas assignés. Pour vérifier plus loin, après le activity.tags.add (* tags) j'ai ajouté cette ligne, activity.verb = "changed" et ensuite activity.save(). Cela change. Cependant, les tags ne sont pas affectés aux activity.tags. Qu'est-ce que je rate? – Aamu