Automatic author in Django admin
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 sho开发者_如何学Gows 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.
It turns out this is pretty simple. You just need to add a queryset
function to your RelatedInline
class, specifying which inline to show. If the returned queryset has at least one member, the first will be shown. If the queryset is empty, a single blank inline will be shown!
class RelatedInline(admin.StackedInline):
model = Related
exclude = ('author',)
max_num = 1
def queryset(request):
return Related.objects.filter(author = request.user)
精彩评论