Django'da ManyToMany ilişkisine aynı anda birden çok nesne nasıl eklenir?


185

Django belgesine dayanarak, bir çok ilişkili ilişkiye eklenebilmek için aynı anda birden fazla nesneyi geçirebilmeliyim ama bir

* TypeError: shahableble type: 'list'

bir listede döküm django queryset geçirmeye çalıştığınızda. Bir Queryset veya ValuesListQueryset iletmek de başarısız gibi görünüyor. For döngüsü kullanmaktan daha iyi bir yol var mı?

Yanıtlar:


320

Kullanım: belgelerdeobject.m2mfield.add(*items) açıklandığı gibi :

add() bir listesini değil, rastgele sayıda argümanı kabul eder.

add(obj1, obj2, obj3, ...)

Bu listeyi bağımsız değişkenlere genişletmek için şunu kullanın: *

add(*[obj1, obj2, obj3])

Zeyilname:

Django obj.save()her öğe için çağrı yapmaz bulk_create(), bunun yerine kullanır .


Yöneticiye bakarsanız, nesneler üzerinde bir for döngüsü yapar ve bunlara kaydetme yapar.
Sam Dolan

3
Kabuktan yapılan kısa bir deney, sdolan'ın aslında (şu anda) yanlış olduğunu gösteriyor. Yani oluşturulan SQL baktığımda sadece tek bir ekleme ifadesi görüyorum: INSERT INTO app_one_twos (one_id, two_id) DEĞERLER (1, 1), (1, 2), (1, 3), (1, 4); Bu Django 1.4'te.
Klaas van Schelven

@KlaasvanSchelven: Bunu oluşturulan sql ile test ettiğimi hatırlamıyorum, ancak yorumuma dayanarak kaynak koduna bir göz attığımdan eminim. Bunun 2 yıldan daha uzun bir süre önce olduğunu unutmayın, bu yüzden işlerin biraz optimize edildiğini umarım.
Sam Dolan

1
@sdolan Hayır geliştirmediler. Sadece test ediyordum.
Saransh Mohapatra

1
Bunu değere göre yapmanın herhangi bir yolu var mı (ör. İd)? Bazen bir nesne listeniz değil, bir nesne değerleri listeniz (yani id'ler) vardır?
Dönüp

48

Eklemek için, bunları bir sorgu kümesinden eklemek istiyorsanız

Misal

# Returns a queryset
permissions = Permission.objects.all()

# Add the results to the many to many field (notice the *)

group = MyGroup.objects.get(name='test')

group.permissions.add(*permissions)

Kimden: Queryset sonuçlarını ManytoManyfield'a ekleyin


3
Bu bir yerine iki sorgu gerçekleştirir :(
DylanYoung

2
Bir listeye dönüştürmenize gerek olmadığını unutmayın. Doğrudan (* izinleri) ekleyin.
BjornW

34

Django 1.9, çoktan çoğa ilişkiye eklemek için ek yollar ekler.

Belgeler: https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager.set

set yeni bir incelik:

>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)

2
setsanırım hep oradaydı. Eskiden e.related_set = new_listeski Djangos'taki görevlendirme ile eşdeğerdi e.related_set.set(new_list). Sadece "açık, örtük olmaktan daha iyi" olduğunu fark ettiler.
DylanYoung

1
Dikkat: Kısa ve öz olmak gerekirse, set mevcut tüm ilişkili modelleri siler. Dolayısıyla, yeni nesnelerin listesini eklemek ve mevcut olanı olduğu gibi tutmak istiyorsanız, add (*
newlist
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.