2

I would like to create a custome admin view with fields with data that I fill manually, meaning that there's no database table behind. In my admin.py I have this so far

class TestAdmin(admin.ModelAdmin):
    pass

admin.site.register(Test, TestAdmin)

and in the models.py

class Test(models.Model):
    test = models.BooleanField(
        default=True
    )

But with this I receive an error

django.db.utils.ProgrammingError: relation "..._test" does not exist

Django is looking up the table in the database but in my model I need only fields which data I fill manually

wasp256
  • 5,943
  • 12
  • 72
  • 119

2 Answers2

2

It seems that you don't really get what a Model and ModelAdmin are. A Model class is the representation of a database table, and a ModelAdmin is a component that provides administration features for this table and it's content. IOW, when you write that "there's no database table behind", you're missing the point somehow: you cannot have a ModelAdmin without a Model, and you cannot have a Model without a database table.

To make a long story short: you'll either have to

1/ use a model or

2/ write the whole view(s) and templates by yourself and plug them into the admin.

For the second solution, see this question (and it's answers), or just google for "django admin views without models" (there are a couple 3rd part apps that are supposed to help plugin custom views in the admin).

Now the first solution might - or not, depending on your exact needs - be as good as the second one, depending on who populates your s3bucket and how. Without a model, you'll have to query the bucket for a file listing each and every time someone accesses your custom admin view, which might get quite costly. If all the uploads to the s3 bucket are under your control, you can use a model to keep a local file listing "cache" and you'll only need to hit s3 when effectively downloading a file. This also gives you the opportunity to store metadata about those files - which can be used for searching / filtering - and eventually to link your s3 files to other models if needed. And of course this means you get your admin for free ;)

Actually even if you don't have control on those uploads, you may still want to use a model for the above reasons and have a background task (cron job or equivalent) that updatees your table from the s3 bucket contents (or - if s3 provides web hooks - have an API endpoint called by s3 on uploads that updates your table).

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

The way that django's ORM works is that all class members of a model class that is an instance of model.Field will map to a column in the database.

It is possible to have model properties that does not map to a database table. You could use a @property instead, for example.

class Test(models.Model):

    @property
    def test(self):
        return get_aws_bucket_value(self.id)

    @test.setter
    def test(self, value):
        set_aws_bucket_value(self.id, value)

You have to implement the aws getter/setter functions yourself.

You can use properties as read-only fields in the django admin class. Be careful about using it in the list view if your getter logic needs to fetch data from a remote server syncronously, since that would be a significant performance bottleneck.

If you want to be able to set values for a setter from the django admin, you would have to write a custom ModelForm for TestAdmin.

It is possible to wrangle Django into doing what you want here. But Django's models and admin are based around the ORM, which means using a relational database as persistant storage. If you don't want that, you can find yourself fighting against and overriding the framework more often than benefiting from Django's "batteries included". This project might be better solved with a less monolithic and less opinionated framework such as Flask instead of Django.

Håken Lid
  • 22,318
  • 9
  • 52
  • 67