Hoe instanties van verschillende modellen vergelijken met hetzelfde abstracte model als hun basis?

Stel dat ik deze modellen heb (niet-praktische code, het is slechts een voorbeeld):

class BaseArticle(models.Model):
    title = models.CharField(max_length=512)
    author = models.ForeignKey(User)
    content = models.TextField()

    class Meta:
        abstract = True

class ArticleWithColor(BaseArticle):
    color = models.CharField(max_length=512)

class ArticleTypeWithSmell(BaseArticle):
    smell = models.CharField(max_length=512)

Bij het opslaan van een artikel (artikel Kleur of Smell) zou ik willen controleren of er andere bestaande exemplaren zijn met dezelfde waarden voor de gedeelde velden (die de BaseArticle-velden zijn).

Met andere woorden: hoe kan ik controleren of er al een ArticleWithColor bestaat met dezelfde waarden voor de velden die het van BaseArticle heeft geërfd als de ArticleWithSmell die ik ga opslaan?

0

2 antwoord

Ik heb mijn antwoord bijgewerkt om alle kindermodellen te doorzoeken. Dat is maar een manier om de lijst met modellen te bouwen. Dit hangt af van uw gebruik.

U kunt waarschijnlijk iets in die zin doen (nog steeds niet getest):

class BaseArticle(models.Model):
    title = models.CharField(max_length=512)
    author = models.ForeignKey(User)
    content = models.TextField()

    _childrens = set()

    # register the model on init
    def __init__(self, *args, **kwargs):
        super(BaseArticle, self).__init__(*args, **kwargs)
        BaseArticle._childrens.add(self.__class__)

    def save(self, *args, **kwargs):
        for model in BaseArticle._childrens:
            query = model.objects.filter(title=self.title, author=self.author, content=self.content)
            # if this Article is already saved, exclude it from the search
            if self.pk and model is self.__class__:
                query.exclude(pk=self.pk)
            if query.count():
                # there's one or more articles with the same values
                do_something()
                break
        super(BaseArticle, self).save(*args, **kwargs)

    class Meta:
        abstract = True
0
toegevoegd
self.objects.filter filtert alleen exemplaren van hetzelfde model, niet de andere modellen die overerven van BaseArticle .
toegevoegd de auteur Alasdair, de bron
O ja! Je hebt helemaal gelijk. Laat me hierover nadenken ...
toegevoegd de auteur Etienne, de bron
Ik heb het antwoord bijgewerkt om dit te verhelpen.
toegevoegd de auteur Etienne, de bron

Als u alleen uzelf wilt beschermen tegen dubbele gegevens, kunt u de optie unique_together gebruiken. Gebruik anders model_to_dict (van django.forms.models import model_to_dict) om modeleigenschappen te nemen en te vergelijken. Ik weet niet zeker of het pk/id teruggeeft als onderdeel van het dictaat, maar als dit het geval is, moet je het verwijderen voordat je het vergelijkt.

0
toegevoegd
Mijn belangrijkste probleem is dat ik zou willen kunnen controleren of modeleigenschappen zijn afgeleid van het abstracte model en of deze eigenschappen dezelfde waarden hebben in andere modellen die zijn afgeleid van het abstracte model.
toegevoegd de auteur LaundroMat, de bron
unique_together werkt niet in de twee tabellen.
toegevoegd de auteur Etienne, de bron