Search code examples
pythondjangodjango-flatpages

Add a field to a Django FlatPage proxy model


This is my models.py:

from django.contrib.flatpages.models import FlatPage

class FlatPageManager(models.Manager):
    def search(self, query=None):
        qs = self.get_queryset()
        if query is not None:
            or_lookup = (Q(title__icontains=query) |
                         Q(content__icontains=query)
                        )
            qs = qs.filter(or_lookup).distinct()
        return qs

class MyFlatPage(FlatPage):
    class Meta:
        proxy = True

    published = models.DateTimeField() # <- this is the field I want to add
    objects = FlatPageManager()

When I do makemigrations I get this error:

./manage.py makemigrations
SystemCheckError: System check identified some issues:

ERRORS:
?: (models.E017) Proxy model 'MyFlatPage' contains model fields.

What am I doing wrong? All I want to do is to add a published field so that I can display the post only on a certain date in the future.

Edit

I have now learned that proxy models do not accept new fields by definition. My next question is then: how can I 'convert' my existing proxy model into something else (without losing my existing data of course) so that I can have an extra published field?


Solution

  • If you set proxy=True you can adjust/enhance the Python-level behavior. You cannot add additional fields to a proxy-model. However, you can set a custom object manager like you did and functions or methods.

    doc

    take a look a model-inheritance #3

    You may add a default behavoir to published

    class FlatPage(models.Model):
       published = models.DateTimeField(auto_now_add=True)
       ...
    

    first update

    You won´t lose data if you extend your FlatPage with a new field. If you want save your data prior call python manage.py dumpdata > db.json

    second update

    models.py

    from django.contrib.flatpages.models import FlatPage
    from django.db import models
    
    class MyCustomFlatePage(FlatPage):
       published = models.DateTimeField(auto_now_add=True)
    

    forms.py

    from django.contrib.flatpages.forms import FlatpageForm
    
    class MyFlatPageForm(FlatpageForm):
        class Meta:
            model = MyFlatPage
            fields = '__all__'
    

    admin.py

    class MyFlatPageAdmin(FlatPageAdmin):
        form = MyFlatPageForm
        fieldsets = (
            (None, {'fields': ('url', 'title', 'content', 'published', 'sites')}),
            (_('Advanced options'), {
                'classes': ('collapse',),
                'fields': (
                    'enable_comments',
                    'registration_required',
                    'template_name',
                ),
            }),
        )
    admin.site.unregister(FlatPage)
    admin.site.register(MyFlatPage, MyFlatPageAdmin)