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.