views:

162

answers:

2

I have a legacy database with tables for documents and authors. A third table defines an ordered many to many relationship between the documents and authors, using foreign keys to the documents and the authors and an integer to specify the author order for a given document.

Using Django 1.1.1 (or SVN), is there a way to edit the document authors and their order in an admin page?

+4  A: 

This is quick and a bit rough, but it should get you close(r).

from django.db import models
from django.contrib import admin

class Document(models.Model):
    name = models.CharField(max_length = 128)

    def __unicode__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length = 128)
    document = models.ManyToManyField(Document, through = 'Foo')

    def __unicode__(self):
        return self.name

class Foo(models.Model):
    document = models.ForeignKey(Document)
    author = models.ForeignKey(Author)
    author_order = models.IntegerField()

class FooInline(admin.TabularInline):
    model = Foo

class DocumentAdmin(admin.ModelAdmin):
    inlines = [ FooInline ]

admin.site.register(Author)
admin.site.register(Document, DocumentAdmin)

http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany http://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects

Jason Leveille
I tried that before, but only one row/entry of Author shows up for editing in the document admin page, even if I specify extra = 3 in the FooInline class.
Luís Marques
I just tested this (w/ 1.1.1) and had the option to initially attach 3 authors when adding a new doc, and 3 more when editing the doc. Not sure where it might be falling down for you, but it seemed to work fine for me.
Jason Leveille
Out of curiousity, did you try inspectdb to see what model representations you get (http://docs.djangoproject.com/en/dev/ref/django-admin/#inspectdb).
Jason Leveille
OK, I've tracked down the cause of the difference. On my legacy database the Foo table does not contain an 'id' primary key column. Instead, it is keyed on all three columns, with the first key being the doc id, then the author id and then the order.The moment I put primary_key=True on a field only one entry shows up in the admin page.
Luís Marques
The model inspectdb outputed was similar to my hand-coded one:class DocumentAuthor(models.Model): doc_id = models.IntegerField(primary_key=True) author_id = models.IntegerField(primary_key=True) order_presentation = models.IntegerField(primary_key=True) class Meta: db_table = u'document_author'
Luís Marques
Great! Could I get an up vote for my response?
Jason Leveille
OK, I changed the legacy database to have an id column with a primary key. Do you know a work around if it was not possible to change it this way, or if the 3 keys really made sense, perhaps for performance? (I'm no RDBMS expert)
Luís Marques
The multi-field primary keys definitely makes sense from an RDBMS view, however the M2M relationship needs a single field primary key (please, someone correct me if I'm wrong). If you still want to ensure the uniqueness of your 3 fields, you should make use of unique_together in your Foo model (http://docs.djangoproject.com/en/dev/ref/models/options/#unique-together).
Jason Leveille
A: 

this might help you too - there is some utility in Django to build models for the legacy databases.

I've built a model for mediawiki database using it. It gets most of the things right, but you'll need to tweak the models a little.

Evgeny