2

ich in meinem Modell kaskadieren-Löschen Sie die folgenden definiert haben:Django Fehler verwandten generic Fremdschlüssel Objekt

class TaskLink(models.Model): 
    task = model.ForeignKey(Task) 
    link_choices = (
     models.Q(app_label="accounts", model="location"), 
     # Other models are also linked to here. 
    ) 
    linked_content_type = \ 
     models.ForeignKey(
      ContentType, 
      limit_choices_to=link_choices 
     ) 
    linked_object_id = models.PositiveIntegerField() 
    linked_object = \ 
     generic.GenericForeignKey(
      'linked_object_content_type', 
      'linked_object_id' 
     ) 

Dieses Modell verbindet Task Objekte mit einem der Modelle im link_choices Tupels. In diesem Fall befindet sich das Modell accounts.Location in dieser Liste.

Mein Problem tritt auf, wenn das Löschen eines Location Objekts in der Kaskadendeletion verwandter TaskLink Objekte resultiert. Deletion schlägt mit der folgenden Fehlermeldung:

django.core.exceptions.FieldError: Cannot resolve keyword 'object_id' into field. Choices are: id, linked_object, linked_object_content_type, linked_object_content_type_id, linked_object_id, task, task_id 

Die Ansicht ist eine Instanz django.views.generic.DeleteView mit nur dem pk_url_kwarg Parameter und Modellsatz (und Berechtigungs Dekoratore zum Versandweg hinzugefügt); Es funktionierte linked_object_fine, bevor ich das TaskLink Modell der Mischung hinzufügte.

Was fehlt mir?

EDIT: Es scheint, dass dies ein Fehler in Django sein kann; Wenn Objekte durch generische Fremdschlüssel kaskadiert werden, ignoriert Django die Feldnamenzeichenfolgen, die Sie an den Konstruktor für das Feld GenericForeignKey übergeben, und sucht stattdessen nach den Feldern content_type und object_id, die in meinem Fall nicht vorhanden waren. Dadurch wird die Anzahl generischer Fremdschlüssel, die ein Modell möglicherweise besitzt, effektiv auf 1 begrenzt, es sei denn, Sie führen Kaskadenlöschung durch.

Ich habe dieses Problem über die Django-Mailingliste gesendet, da dieses Verhalten beabsichtigt sein könnte.

Antwort

2

Umbenennungsfeldnamen von Aufgaben-Verknüpfungs

linked_content_type >>> content_type 
linked_object_id >>> object_id 

oder Pre-Signal schreiben, während "Location" Objekt löschen verknüpfte Objekt "Tasklink"

für kundenspezifische Signale
from django.db.models.signals import pre_delete 
from django.dispatch import receiver 

@receiver(pre_delete, sender=Location, dispatch_uid='location_delete_signal') 
def deleted_gfk_TaskLink(sender, instance, using, **kwargs): 
    ctype = ContentType.objects.get_for_model(sender) 
    obj = TaskLink.objects.get(linked_content_type=ctype, linked_object_id=instance.id) 
    obj.delete() 

Bezug zu löschen:
https://micropyramid.com/blog/using-djangos-built-in-signals-and-writing-custom-signals/

+0

Kennzeichnung als die Antwort, weil dies das Problem für meinen Fall löst, aber ich denke, es ist wichtig zu beachten: die Art und Weise Django h andles generische Fremdschlüssel verhindern, dass Modelle mehr als eins haben, wenn Sie sich auf Kaskadenlöschung verlassen wollen. – Adam

Verwandte Themen