2017-10-14 2 views
1

Je ne peux pas ajouter ManyToManyField objets même après avoir suivi la docImpossible d'ajouter des objets ManyToManyField dans Django

models.py

class Label(models.Model): 
    ... 
    name = models.CharField(blank=False, max_length=100) 

class Template(models.Model): 
    ... 
    labels = models.ManyToManyField(Label, blank=True, related_name="labels") 

Et puis

>>> from content.models import Label, Template 
>>> l1 = Label.objects.get_or_create(name='one') # saves in db 
>>> l2 = Label.objects.get_or_create(name='two') # saves in db 
>>> t1 = Template.objects.get(pk=1)   # loads existing 
>>> t1.labels.set([l1,l2])      # fails 

jette cette erreur

Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1007, in set 
    self.add(*new_objs) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 934, in add 
    self._add_items(self.source_field_name, self.target_field_name, *objs) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1083, in _add_items 
    '%s__in' % target_field_name: new_ids, 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/query.py", line 784, in filter 
    return self._filter_or_exclude(False, *args, **kwargs) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/query.py", line 802, in _filter_or_exclude 
    clone.query.add_q(Q(*args, **kwargs)) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1250, in add_q 
    clause, _ = self._add_q(q_object, self.used_aliases) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1276, in _add_q 
    allow_joins=allow_joins, split_subq=split_subq, 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1206, in build_filter 
    condition = lookup_class(lhs, value) 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/lookups.py", line 24, in __init__ 
    self.rhs = self.get_prep_lookup() 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 56, in get_prep_lookup 
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs] 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 56, in <listcomp> 
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs] 
    File "/path/env3tt/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 966, in get_prep_value 
    return int(value) 
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Label' 

J'utilise Django 1.11 sur Python 3.6.

Répondre

4

Vous utilisez get_or_create qui renvoie un nombre de (object, created), pas seulement un objet.

Donc l1 et l2 ne sont pas Label comme vous le supposez, mais des tuples. Transmettre cela au gestionnaire plusieurs-à-plusieurs ne fonctionnera pas.

Changer votre code comme suit:

from content.models import Label, Template 
# Ignore the second item returned by get_or_create 
l1, _ = Label.objects.get_or_create(name='one') 
l2, _ = Label.objects.get_or_create(name='two') # 
t1 = Template.objects.get(pk=1) 
t1.labels.set([l1,l2]) 
+0

correcte. J'aurais dû chercher 'get_or_create()' dans le document. –