Help: Probem z modelem w Django (powiązane artykuły)

Męczę się już trochę z tym problemem, a być może ktoś będzie znał rozwiązanie.

Mam model:

class Article(models.Model):
    title = models.CharField(max_length = 120, verbose_name = u'Tytuł')
    long_content = models.TextField(verbose_name = u'Treść')
    short_content = models.TextField(verbose_name = u'Krótka treść')
    category = models.ForeignKey(ArticleCategory, verbose_name = u'Kategoria')
    slug = models.SlugField(max_length = 120, unique=True, verbose_name = u'Odnośnik')
    related_articles = models.ManyToManyField("Article", verbose_name = u'Powiązane artykuły', blank = True)

Pytanie brzmi:

Jak zrobić aby artykuły były powiązane dwustronnie? To znaczy jeśli, dodam w panelu administracyjnym, że „Artykuł nr 1” jest powiązany z „Artykuł nr 2”, to jeśli wejdę na stronę edycji „Artykuł nr 2” to będę widział odpowiednie powiązanie z „Artykuł nr 1” ?

8 thoughts on “Help: Probem z modelem w Django (powiązane artykuły)

  1. A po co tak? Rozumiem, że nie chcesz 2 razy dodawać, ale wystarczy wyfiltrować np. tak:
    a1 = Article.objects.get(pk=1)
    lista_pk = a1.related_articles.all().values_list('id',flat=True)
    lista_pk.extend( Article.objects.filter( related_articles___pk__in=[a1.id,]).values_list('id',flat=True) )

  2. No dobra, wiem jak to pobrać 😉 Ale jak zrobić, żeby za każdym razem przy dodawaniu, aktualizowaniu, usuwaniu działało to w obie strony(na dwóch artykułach). Założenie, jest takie, że panel administracyjny będzie obsługiwać osoba, która nie będzie znała całego systemu. Kiedy zobaczy w panelu że jest zaznaczony powiązany artykuł no to super, ale jeśli przejdzie do tego powiązanego artykułu w panelu to może zobaczyć, że nie jest on powiązany w drugą stronę. Chciałbym uniknąć takich niejasności 😉 No chyba, że można to jakoś od strony panelu załatwić ?

    Mam nadzieję, że nie zakręciłem 😛

  3. proszę bardzo, mam nadzieję że o to chodziło:
    w models.py wklejasz
    (coś markdown nie działa 🙂 )

    from django.db.models import signals
    def m2m(sender, instance, action, reverse, model, pk_set, **kwargs):
    –if action == „post_add”:
    —-for i in Article.objects.filter( pk__in=pk_set).exclude( related_articles__pk__in=[ instance.id, ] ):
    ——i.related_articles.add( instance )
    –if action in [ „post_remove”,”post_clear”,]:
    —-for i in Article.objects.filter( pk__in=pk_set, related_articles__pk__in=[ instance.id, ] ):
    ——i.related_articles.remove( instance )

    signals.m2mchanged.connect( m2m,sender=Article.relatedarticles.through )
    `

    wynik z schella:

    from articles.models import *
    Article.objects.all().delete()

    a1 = Article.objects.create( title=’a1′, slug=’a1′)
    a2 = Article.objects.create( title=’a2′, slug=’a2′)

    a1.related_articles.add( a2 )

    a1.relatedarticles.all()
    [<Article: a2>]
    a2.related
    articles.all()
    [<Article: a1>]

    a2.related_articles.remove( a1 )

    a1.relatedarticles.all()
    []
    a2.related
    articles.all()
    []

  4. Sprawdziłem jeszcze przed chwilą na prostym modelu i relacja m2m z ‚self’ jest symetryczna, czyli zachowuje się właśnie tak jak chcesz – zachowanie to można wyłączyć za pomocą argumentu symmetrical=False

  5. Nie działało ponieważ było models.ManyToManyField(„Article”) a nie models.ManyToManyField(„self”). Sam się na to nadziałem 🙂 Czasem warto doczytać dokumentację 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *