I have a Django application using the sites framework. I have a Category model and a Topic model. The Topic model has a "category" attribute pointing to a specific Category object. Both of these models have "site" attributes linking them to specific sites in the Django application. All of these websites are hosted on the same server.
What I'm noticing is that, when I create/update an object (Topic) in the admin - and set the topic's foreign key field (category) to a category that is not on the site configured in the SITE_ID setting - I get this error message:
category instance with id X does not exist
When I change the SITE_ID
in settings.py
, I can now set the topic's category to a category on that site, but not on any other sites.
Here's a chart to help you visualize this:
There are two relevant models here, Category and Topic:
class Category(models.Model):
name = models.CharField(max_length=128)
slug = models.SlugField()
description = RichTextUploadingField(
blank=True,
default='',
verbose_name='Category Description',
help_text='''Category description to be displayed on category page
goes here'''
)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
on_site = CurrentSiteManager()
objects = models.Manager()
class Meta:
verbose_name_plural = 'categories'
ordering = ['name']
class Topic(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
name = models.CharField(max_length=128)
slug = models.SlugField()
description = RichTextUploadingField(
blank=True,
default='',
verbose_name='Topic Description',
help_text='''Topic description to be displayed on topic page
goes here'''
)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
on_site = CurrentSiteManager()
objects = models.Manager()
The TopicAdmin is configured to retrieve the categories and topics for all the sites:
@admin.register(Topic)
class TopicAdmin(admin.ModelAdmin):
list_display = ['name', 'site']
save_as = True
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'category':
kwargs['queryset'] = Category.objects.all().order_by('name')
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_queryset(self, request):
return Topic.objects.all()
Any ideas of what to do here to make it so that topics save with the appropriate category?
I've tried hooking into a bunch of different ModelAdmin methods, but I haven't had any success yet.
The first manager defined on a model is used by certain parts of Django including the admin, the first manager on your models is a CurrentSiteManager
which limits the results to the current site.
Put a regular models.Manager
first for each model so that the default manager used is not limited to the current site
class Category(models.Model):
...
objects = models.Manager()
on_site = CurrentSiteManager()
class Topic(models.Model):
...
objects = models.Manager()
on_site = CurrentSiteManager()