Reputation: 3560
I have a database of articles that are reused across multiple Django sites. There is also some site-specific information for each Article, stored in the SiteArticle model. One bit of information is a list of site-specific tags for each SiteArticle. Here's the models.py
:
class Article(models.Model):
sites = models.ManyToManyField(Site, through='SiteArticle')
class SiteArticle(models.Model):
site = models.ForeignKey(Site)
article = models.ForeignKey(Entiteit)
tags = models.ManyToManyField('Tag', blank=True)
class Tag(models.Model):
name = models.CharField(max_length=255)
site = models.ForeignKey(Site, related_name='tags')
I use an inline admin to edit and add the SiteArticle objects of each Article. Here's admin.py
:
class InlineSiteArticle(admin.StackedInline):
model = SiteArticle
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
inlines = [InlineSiteArticle]
When editing an article, I would like the inline SiteArticle forms to only display the tags of the relevant site. I tried overriding the formfield_for_manytomany() method, but here I don't have access to instance
variable (which should be an instance of the current SiteArticle) that I need to filter the queryset:
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "tags":
kwargs["queryset"] = instance.site.tags.all()
^^^^^^^^
return super(InlineSiteArticle, self).formfield_for_manytomany(db_field, request, **kwargs)
I already looked at this Stack Overflow answer which solves a very related problem. In my case, however, I do not need access to the "parent" instance, but simply to the instance of the current form's SiteArticle object. How can I solve this?
EDIT -- I already figured out that get_formset() does get an instance passed in. However, this instance is an Article, not the SiteArticle needed to filter the queryset.
Upvotes: 0
Views: 98
Reputation: 3560
Here's the answer I figured out myself. Feel free to edit, comment, or provide a better solution!
I created a custom form for editing SiteArticles, which I passed to the ArticleAdmin using the form
option of ModelAdmin. In the constructor of this form I performed the filtering of the queryset based on the current model instance, which is now available as self.instance
.
class CustomSiteArticleForm(forms.ModelForm):
class Meta:
model = SiteArticle
fields = '__all__'
def __init__(self, *args, **kwargs):
super(CustomSiteArticleForm, self).__init__(*args, **kwargs)
if self.instance.pk:
self.fields['tags'].queryset = self.instance.site.tags.all()
else:
self.fields['tags'].queryset = Tag.objects.none()
Upvotes: 1