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
ManyToManyField
relationclass 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_set
och påpizza.toppings
.
- add(*objs, bulk=True, through_defaults=None)¶
- aadd(*objs, bulk=True, through_defaults=None)¶
Asynkron version:
aadd
Lä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=False
fö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 (argumentetbulk
finns 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_add
ochpost_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_defaults
för att ange värden för den nya :ref:intermediate model <intermediary-manytomany>`-instansen (instanserna), om det behövs. Du kan använda callables som värden i ordlistan ``through_defaults
och 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:
acreate
Skapar 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
blog
tillcreate()
. Django räknar ut att det nyaEntry
-objektetsblog
-fält ska sättas tillb
.Använd argumentet
through_defaults
för att ange värden för den nya instansen :ref:intermediate model <intermediary-manytomany>
, 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:
aremove
Tar 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 borte
frånb.entry_set()
likvärdigt med att görae.blog = None
, och eftersomblog
ForeignKey
inte 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=False
anropas istället metodensave()
för varje enskild modellinstans. Detta utlöser signalernapre_save
ochpost_save
och 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:
aclear
Tar 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=True
och 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:
aset
Byt 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=True
anropas 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_defaults
för att ange värden för den nya :ref:intermediate model <intermediary-manytomany>`-instansen (instanserna), om det behövs. Du kan använda callables som värden i ordlistan ``through_defaults
och 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.