views:

29

answers:

0

Hi, all. I'm working on the admin for my django site, and I've run into an obstacle.

I've got an Entry model and a Related model. The Related model has two foreign key fields: one to the Entry model (entry) and one to django's User model (author). The Related model is considered a "sub-model" of the Entry model, and each user can only have one Related per Entry.

In the admin, Related is edited inline with Entry. As I have it, the admin shows only one extra Related at a time, and it automatically fills the author field with the current user:

from django.contrib import models
from django.contrib.auth.models import User

class Entry(models.Model):
    pass

class Related(models.Model):
    entry = models.ForeignKey(Entry)
    author = models.ForeignKey(User)
    class Meta:
        unique_together = ('entry', 'author')




from django.contrib import admin

class RelatedInline(admin.StackedInline):
    model = Related
    exclude = ('author',)
    max_num = 1

class EntryAdmin(admin.ModelAdmin):
    inlines = (RelatedInline,)
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in filter(lambda obj: isinstance(obj, Related), instances):
             if instance.__dict__.get('author', None) is None:
                 instance.author = request.user
                 instance.save()
        formset.save_m2m()

The problem is that if a user wants to edit an entry which already has a Related by anyone, then only that one related field will be shown.

If possible, I wonder if anyone has any ideas about how I could keep a setup similar to this, but have the admin automatically display the user's related if it exists and an empty form if it doesn't. Barring that, I would just get rid of the line max_num = 1 and replace it with extra = 1. Of course, this would mean that a "new related" form would show even if the user already had one for the current entry, so I wonder if anyone has any idea about how I would catch a possible IntegrityError and let the user know that an error had occurred.