내 모델 :
class Sample(models.Model):
users = models.ManyToManyField(User)
나는 모두를 저장할 user1
와 user2
그 모델 :
user1 = User.objects.get(pk=1)
user2 = User.objects.get(pk=2)
sample_object = Sample(users=user1, users=user2)
sample_object.save()
나는 그것이 틀렸다는 것을 알고 있지만, 내가하고 싶은 것을 얻을 것이라고 확신합니다. 어떻게 하시겠습니까?
답변
저장되지 않은 객체에서 m2m 관계를 작성할 수 없습니다. pk
s 가 있으면 다음을 시도하십시오.
sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)
업데이트 : saverio의 답변을 읽은 후에 문제를 좀 더 깊이 조사하기로 결정했습니다. 내 결과는 다음과 같습니다.
이것은 나의 원래 제안이었다. 작동하지만 최적은 아닙니다. (참고 : Bar
s 및 a Foo
대신 User
s 및 a를 사용 Sample
하고 있지만 아이디어를 얻습니다).
bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1)
foo.bars.add(bar2)
총 7 개의 쿼리를 생성합니다.
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)
우리가 더 잘할 수 있다고 확신합니다. add()
메소드에 여러 객체를 전달할 수 있습니다 .
bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1, bar2)
보시다시피 여러 객체를 전달하면 하나가 저장됩니다 SELECT
.
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)
객체 목록을 할당 할 수도 있다는 것을 알지 못했습니다.
bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars = [bar1, bar2]
불행히도, 그것은 하나의 추가를 만듭니다 SELECT
:
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)
pk
saverio가 제안한대로 s 목록을 할당 해 봅시다 :
foo = Foo()
foo.save()
foo.bars = [1,2]
두 개를 가져 오지 않기 때문에 두 Bar
개의 SELECT
명령문 을 저장 하여 총 5 개를 얻습니다.
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)
그리고 승자는:
foo = Foo()
foo.save()
foo.bars.add(1,2)
pk
s를 전달 add()
하면 총 4 개의 쿼리가 제공됩니다.
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)
답변
장래 방문자를 위해 django 1.4 의 새로운 bulk_create 를 사용하여 2 개의 쿼리 로 객체와 모든 m2m 객체를 만들 수 있습니다 . 당신이 필요하지 않은 경우이 만 사용할 수 있습니다 어떤 () 메소드 또는 신호 저장과 데이터에 대한 사전 또는 사후 처리를. 당신이 삽입하는 것은 DB에있을 것입니다 정확히
필드에서 “관통”모델을 지정하지 않고도이 작업을 수행 할 수 있습니다. 완성도를 높이기 위해 아래 예는 원본 포스터가 요청한 내용을 모방하는 빈 사용자 모델을 만듭니다.
from django.db import models
class Users(models.Model):
pass
class Sample(models.Model):
users = models.ManyToManyField(Users)
이제 쉘 또는 다른 코드에서 2 명의 사용자를 작성하고 샘플 오브젝트를 작성하고 해당 샘플 오브젝트에 사용자를 대량 추가하십시오.
Users().save()
Users().save()
# Access the through model directly
ThroughModel = Sample.users.through
users = Users.objects.filter(pk__in=[1,2])
sample_object = Sample()
sample_object.save()
ThroughModel.objects.bulk_create([
ThroughModel(users_id=users[0].pk, sample_id=sample_object.pk),
ThroughModel(users_id=users[1].pk, sample_id=sample_object.pk)
])
답변
장고 1.9
간단한 예 :
sample_object = Sample()
sample_object.save()
list_of_users = DestinationRate.objects.all()
sample_object.users.set(list_of_users)
답변
RelatedObjectManagers는 모델의 필드와 다른 “속성”입니다. 당신이 찾고있는 것을 달성하는 가장 간단한 방법은
sample_object = Sample.objects.create()
sample_object.users = [1, 2]
추가 쿼리와 모델 작성없이 사용자 목록을 할당하는 것과 같습니다.
단순하지 않고 쿼리 수가 귀찮은 경우 최적의 솔루션에는 세 가지 쿼리가 필요합니다.
sample_object = Sample.objects.create()
sample_id = sample_object.id
sample_object.users.through.objects.create(user_id=1, sample_id=sample_id)
sample_object.users.through.objects.create(user_id=2, sample_id=sample_id)
‘사용자’목록이 비어 있다는 것을 이미 알고 있으므로 마음대로 만들 수 있습니다.
답변
이런 방식으로 관련 객체 세트를 교체 할 수 있습니다 (Django 1.9의 새로운 기능).
new_list = [user1, user2, user3]
sample_object.related_set.set(new_list)
답변
누군가 David Marbles가 자신을 참조하는 ManyToMany 필드에 대답하려고합니다. 관통 모델의 ID를 “to_’model_name_id”및 “from_’model_name’_id”라고합니다.
그래도 작동하지 않으면 장고 연결을 확인할 수 있습니다.
답변
