0

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?

HBMCS
  • 686
  • 5
  • 25

1 Answers1

1

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)
Klim Bim
  • 484
  • 2
  • 7
  • Thank you. So, in this case it would become a 'Multi-table inheritance', is that right? – HBMCS Jun 14 '21 at 13:44
  • Also, are you saying I should take the 'Meta proxy' out altogether, and use `class MyFlatPage(FlatPage):` to extend FlatPage instead? It is not 'my' FlatPage model. It is part of the FlatPages app (https://docs.djangoproject.com/en/3.2/ref/contrib/flatpages/). – HBMCS Jun 14 '21 at 14:09
  • PS: even extending the model with `class MyFlatPage(FlatPage):...` it doesn't work. When I load the customised form in the admin backend I get a 'published is not a valid field' error. – HBMCS Jun 14 '21 at 22:19
  • 1
    @HBMCS What section displays your model at the admin panel? Your custom model won´t be under `FLAT PAGES`-section. You should find it at your own app. I updated my answer. My test worked with a custom flatepage-model – Klim Bim Jun 15 '21 at 06:20
  • Just a side note: `auto_now_add=True` will set the field as read-only, so I either need to add `readonly_fields = ('published,)` to the `MyFlatPageAdmin` class or set `null=True, blank=True` in the model's field definition. – HBMCS Jun 23 '21 at 11:18