programing

다양한 필드를 가진 장고 모델의 객체를 만드는 방법은 무엇입니까?

linuxpc 2023. 6. 20. 21:25
반응형

다양한 필드를 가진 장고 모델의 객체를 만드는 방법은 무엇입니까?

내 모델:

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 관계를 만들 수 없습니다.만약 당신이 가지고 있다면.pks, 사용해 보십시오.

sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)

업데이트 : saverio님의 답변을 읽고 조금 더 자세히 조사해보기로 했습니다.여기 제 연구 결과가 있습니다.

이것이 저의 원래 제안이었습니다.효과는 있지만 최적은 아닙니다.(참고: 사용 중입니다.Bar모래땅Foo대신에User모래땅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)

다음 목록을 할당해 보겠습니다.pks, saverio가 제안한 것처럼:

foo = Foo()
foo.save()
foo.bars = [1,2]

우리가 그 둘을 데려오지 않기 때문에.Bars, 우리는 두개를 저장합니다.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스토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)

향후 방문자를 위해 새로운 bulk_create in django 1.4를 사용하여 2개의 쿼리로 객체와 해당 m2m 객체를 모두 생성할 수 있습니다.이 기능은 save() 메서드 또는 신호를 사용하여 데이터를 사전 또는 사후 처리할 필요가 없는 경우에만 사용할 수 있습니다.당신이 삽입하는 것은 정확히 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)

관련 개체 관리자는 모델의 필드와 다른 "속성"입니다.당신이 찾고 있는 것을 성취하는 가장 간단한 방법은

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)

이미 '사용자' 목록이 비어 있다는 것을 알고 있기 때문에 아무 생각 없이 만들 수 있습니다.

다음과 같은 방법으로 관련 개체 집합을 바꿀 수 있습니다(장고 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"라고 합니다.

그래도 안 되면 장고 연결을 확인할 수 있습니다.

언급URL : https://stackoverflow.com/questions/6996176/how-to-create-an-object-for-a-django-model-with-a-many-to-many-field

반응형