Newby Frage: Manytomany Relation mit mysql und Serendipity

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
3epnm
User
Beiträge: 2
Registriert: Sonntag 8. Februar 2009, 15:32

Sonntag 8. Februar 2009, 15:47

Hallo,

ich bin noch ziemlich neu bei python/django und versuche, per python auf die mysql Datenbank meiner Serendipity Installation zuzugreifen (komme von php).

Dabei geht es mir darum, das mysql-schema als python model abzubilden, um Einträge zusammen mit den Kategorien verknüpfen zu können.

Das mysql schema ist recht einfach:

serendipity_category ( categoryid [pk], category_name [varchar] )
serendipity_entrycat ( entryid [fk], categoryid [fk])
serendipity_entries (id [pk],. title [varchar], body [varchar])

Allerdings ist das Schema bei Serendipity nicht so kanonisch, wie man es sich wünschen würde. Trotzdem denke ich, das es möglich sein sollte, ein Model für die drei Tabellen in Python zu erstellen, welche es erlauben, zu den entries die category mit anzuzeigen.

Mein Model sieht ggw. so aus:

Code: Alles auswählen

from django.db import models

class Category(models.Model):
        categoryid = models.IntegerField(primary_key=True)
        category_name = models.CharField(maxlength=200)
        
        def __str__(self):
                return self.category_name
        
        class Admin:
                pass

class Entries(models.Model):
        id = models.IntegerField(primary_key=True)
        title = models.CharField(maxlength=200)
        body = models.TextField()
        extended = models.TextField()
        timestamp = models.CharField(maxlength=200)
        last_modified = models.CharField(maxlength=200)

        category = models.ManyToManyField(Entrycat)

        def __str__(self):
                return self.title

        class Admin:
                pass

class Entrycat(models.Model):
        entryid = models.ForeignKey(Entries, related_name="Entries.id")
        categoryid = models.ForeignKey(Category, related_name="Category.categoryid")
Hat jemand einen Tip, wie ich weiterkomme. Ziel ist es, zunächst in dem Django Adminbackend für die Einträge eine Auswahlliste o.ä. für die Kategorie zu erhalten.

thanx
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Samstag 14. Februar 2009, 10:43

Wenn du das existierende Schema weiter benutzen willst, kannst du die Spalten- und Tabellennamen bei Django auch vorgeben. So kommst du recht nah ran:

Code: Alles auswählen

from django.db import models

class Category(models.Model):
    id = models.AutoField(db_column='categoryid', primary_key=True)
    name = models.CharField(db_column='category_name', max_length=255)
    
    class Meta:
        db_table = 'serendipity_category'
    
class Entry(models.Model):
    title = models.CharField(max_length=255)
    body = models.CharField(max_length=255)
    
    categories = models.ManyToManyField(Category, related_name='entries', db_table='serendipity_entrycat')

    class Meta:
        db_table = 'serendipity_entries'
Die Join-Tabelle enthält jedoch noch eine "id"-Spalte, die das Original bei dir nicht hat. Ob man die unterdrücken kann, weiß ich nicht, befürchte jedoch, es wird nicht gehen.

Eine andere Alternative, wo du dann auch noch die Namen der Spalten anpassen kannst, wäre das "through"-Attribut einer ManyToMany-Relation.

Stefan
3epnm
User
Beiträge: 2
Registriert: Sonntag 8. Februar 2009, 15:32

Sonntag 15. Februar 2009, 13:59

Das die mxn Tabellen bei s9y keine eigene ids haben und dies beim db model von django zu Problemen führt hat mich dazu bewogen, die Verknüpfung von Hand herzustellen, indem ich mir erstmal die Id's der Einträge per natives sql besorge und dann die Entryobjekte damit Filter. Optimal ist das nicht, aber bei meiner Anwendung erstmal vernachlässigbar.

Code: Alles auswählen

class Category(models.Model):
        def getEntries(self, limit):
                from django.db import connection
                cursor = connection.cursor()
                cursor.execute("SELECT entries.id, entries.timestamp FROM
                                            serendipity_category AS cat, serendipity_entrycat AS rel,
                                            serendipity_entries as entries WHERE entries.isdraft != 1 
                                            AND rel.entryid = entries.id 
                                            AND rel.categoryid = cat.categoryid 
                                            AND cat.categoryid = %s 
                                            ORDER BY entries.timestamp 
                                            DESC Limit %s", [self.categoryid, limit])
                entryids = [int(e[0]) for e in cursor.fetchall()]
                myEntries = Entries.objects.filter(id__in=entryids).order_by('timestamp').reverse()
                return myEntries
 
Entscheidend ist bei mir, das ich die Einträge irgendwie als ordentliche Django Objekte bekomme. Wenn jemanden da was einfällt, was eher djangophil währe, schau ich mir das gerne an.

Trotzdem vielen Dank für die Mühe.
Antworten