Search code examples
djangofeincms

FeinCMS, intermediate model on content type field


I'm trying to accomplish the following:

class DownloadContentFiles(models.Model):
    download_content = models.ForeignKey('DownloadContent')
    media_file = models.ForeignKey(MediaFile)

class DownloadContent(models.Model):
    files = models.ManyToManyField(MediaFile, through=DownloadContentFiles)

    class Meta:
        abstract=True

I can see why this doesn't work. Because of the abstract on DownloadContent.

Is there a workaround to specify a intermediate model for contenttype fields?


Solution

  • Generally, if you need more informations when creating a field (such as a list of choices) or a concrete Django model (as you do), you can use initialize_type for that.

    class DownloadContent(models.Model):
        @classmethod
        def initialize_type(cls):
            cls.add_to_class('files', ... your model field ...)
    

    The MediaFileContent uses this method to add the type selector:

    https://github.com/feincms/feincms/blob/master/feincms/content/medialibrary/models.py#L58

    However, in your case this does not work because you'd also have to create the through model dynamically. The reason for that is that for each concrete DownloadContent, you'd need another concrete DownloadContentFiles model.

    You could achieve this by using the type built-in to dynamically create new DownloadContentFiles concrete classes (beware of name clashes when using DownloadContent with different CMS bases such as page.Page and elephantblog.Entry).

    Maybe a simpler way to achieve what you want:

    • Add a Downloads model somewhere, and add the files ManyToManyField to this class instead
    • The DownloadContent only contains a ForeignKey(Downloads)

    Yes, you need another model. It might be worth it because you can build a better editing interface for Downloads, and the page editor is also simplified because you only have to select one of the already existing Downloads models for showing them on a page.