Relaterade objekt referens¶
- class RelatedManager¶
En ”relaterad manager” är en manager som används i ett relaterat sammanhang en-till-många eller många-till-många. Detta sker i två fall:
Den ”andra sidan” av en
ForeignKey-relation. Det vill säga:from django.db import models class Blog(models.Model): # ... pass class Entry(models.Model): blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)
I exemplet ovan kommer metoderna nedan att vara tillgängliga för förvaltaren
blog.entry_set.Båda sidor av en
ManyToManyFieldrelationclass Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)
I det här exemplet kommer metoderna nedan att vara tillgängliga både på
topping.pizza_setoch påpizza.toppings.
- add(*objs, bulk=True, through_defaults=None)¶
- aadd(*objs, bulk=True, through_defaults=None)¶
Asynkron version:
aaddLägger till de angivna modellobjekten i den relaterade objektuppsättningen.
Exempel:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.
I exemplet ovan, när det gäller en
ForeignKey-relation, användsQuerySet.update()för att utföra uppdateringen. Detta kräver att objekten redan är sparade.Du kan använda argumentet
bulk=Falseför att istället låta den relaterade hanteraren utföra uppdateringen genom att anropae.save().Om du använder
add()med en many-to-many-relation kommer dock ingasave()-metoder att anropas (argumentetbulkfinns inte), utan relationerna skapas medQuerySet.bulk_create(). Om du behöver köra någon anpassad logik när en relation skapas, lyssna påm2m_changed-signalen, som kommer att utlösapre_addochpost_add-åtgärder.Om du använder
add()på en relation som redan finns kommer relationen inte att dupliceras, men den kommer fortfarande att utlösa signaler.För många-till-många-relationer accepterar
add()antingen modellinstanser eller fältvärden, normalt primärnycklar, som argumentet*objs.Använd argumentet
through_defaultsför att ange värden för den nya intermediate model-instansen (instanserna), om det behövs. Du kan använda callables som värden i ordlistanthrough_defaultsoch de kommer att utvärderas en gång innan någon eller några mellanliggande instanser skapas.
- create(through_defaults=None, **kwargs)¶
- acreate(through_defaults=None, **kwargs)¶
Asynkron version:
acreateSkapar ett nytt objekt, sparar det och lägger till det i den relaterade objektuppsättningen. Returnerar det nyskapade objektet:
>>> b = Blog.objects.get(id=1) >>> e = b.entry_set.create( ... headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1) ... ) # No need to call e.save() at this point -- it's already been saved.
Detta är likvärdigt med (men enklare än):
>>> b = Blog.objects.get(id=1) >>> e = Entry(blog=b, headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1)) >>> e.save(force_insert=True)
Observera att det inte finns något behov av att ange nyckelordsargumentet för den modell som definierar relationen. I exemplet ovan skickar vi inte parametern
blogtillcreate(). Django räknar ut att det nyaEntry-objektetsblog-fält ska sättas tillb.Använd argumentet
through_defaultsför att ange värden för den nya instansen intermediate model, om det behövs. Du kan använda callables som värden i ordlistanthrough_defaults.
- remove(*objs, bulk=True)¶
- aremove(*objs, bulk=True)¶
Asynkron version:
aremoveTar bort de angivna modellobjekten från den relaterade objektuppsättningen:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
I likhet med
add()anropase.save()i exemplet ovan för att utföra uppdateringen. Om du använderremove()med en många-till-många-relation raderas dock relationerna medQuerySet.delete()vilket innebär att ingasave()-metoder anropas; lyssna påm2m_changed-signalen om du vill köra anpassad kod när en relation raderas.För många-till-många-relationer accepterar
remove()antingen modellinstanser eller fältvärden, normalt primärnycklar, som argumentet*objs.För
ForeignKey-objekt finns denna metod endast omnull=True. Om det relaterade fältet inte kan sättas tillNone(NULL), kan ett objekt inte tas bort från en relation utan att läggas till i en annan. I exemplet ovan är att ta bortefrånb.entry_set()likvärdigt med att görae.blog = None, och eftersomblogForeignKeyinte harnull=Trueär detta ogiltigt.För
ForeignKey-objekt accepterar denna metod ettbulk-argument för att styra hur operationen ska utföras. OmTrue(standard) användsQuerySet.update(). Ombulk=Falseanropas istället metodensave()för varje enskild modellinstans. Detta utlöser signalernapre_saveochpost_saveoch sker på bekostnad av prestanda.För många-till-många-relationer finns inte nyckelordsargumentet
bulk.
- clear(bulk=True)¶
- aclear(bulk=True)¶
Asynkron version:
aclearTar bort alla objekt från den relaterade objektuppsättningen:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
Observera att detta inte raderar de relaterade objekten - de kopplas bara isär.
Precis som
remove()ärclear()endast tillgänglig påForeignKey`därnull=Trueoch den accepterar också nyckelordsargumentetbulk.För många-till-många-relationer finns inte nyckelordsargumentet
bulk.
- set(objs, bulk=True, clear=False, through_defaults=None)¶
- aset(objs, bulk=True, clear=False, through_defaults=None)¶
Asynkron version:
asetByt ut uppsättningen av relaterade objekt:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
Denna metod accepterar ett
clear-argument för att styra hur operationen ska utföras. OmFalse(standard), tas de element som saknas i den nya uppsättningen bort medremove()och endast de nya läggs till. Omclear=Trueanropas istället metodenclear()och hela uppsättningen läggs till på en gång.För
ForeignKey-objekt skickasbulk-argumentet vidare tilladd()ochremove().För många-till-många-relationer finns inte nyckelordsargumentet
bulk.Observera att eftersom
set()är en sammansatt operation kan den vara föremål för tävlingsvillkor. Exempelvis kan nya objekt läggas till i databasen mellan anropet tillclear()och anropet tilladd().För många-till-många-relationer accepterar
set()en lista med antingen modellinstanser eller fältvärden, normalt primärnycklar, somobjs-argument.Använd argumentet
through_defaultsför att ange värden för den nya intermediate model-instansen (instanserna), om det behövs. Du kan använda callables som värden i ordlistanthrough_defaultsoch de kommer att utvärderas en gång innan någon eller några mellanliggande instanser skapas.
Observera
Observera att
add(),aadd(),create(),acreate(),remove(),aremove(),clear(),aclear(),set()ochaset()alla tillämpar databasändringar omedelbart för alla typer av relaterade fält. Med andra ord behöver du inte anropasave()/asave()` i någon av ändarna av relationen.Om du använder
prefetch_related(), rensar metodernaadd(),aadd(),remove(),aremove(),clear(),aclear(),set()ochaset()den prefetchade cachen.