Restricting the editing interface using proxy models

    The administrative interface of the django allows you to configure access rights to objects of various applications. For any model of any application, you can allow the user three actions: add new objects, edit and delete existing objects.

    But what if we want to allow the user to edit only part of the fields? And at the same time, leave the opportunity to other users to edit all the fields. Proxy models

    will help us . In jango terminology, a proxy model is an object that has the interface of a regular model, but is not tied to a database, or rather, it is tied to data from another model. What is it for? The django documentation uses the following example. We want model objects

    auth.Userpossessed an additional method. To do this, we create a proxy model based on the model auth.User, describe this method there and use this proxy model instead of the original one where necessary.

    Let's get back to our task. Proxy models are useful in that we can prevent the user from working with the original model, allow him access to the proxy model and configure the editing form so that only allowed fields are available.

    Let's imagine that we have the following model:

    class Article(models.Model):
        title = models.CharField(...)
        body = models.CharField(...)
        tags = models.CharField(...)
    


    We want the editor to be able to go to the admin panel, see the list of articles, change tags, but cannot change the title or body of the article.

    Let's create a proxy model for starters:

    class ArticleEditProxy(Article):
        class Meta:
            proxy = True
    


    Now register this model inadmin.siteand assign it a special form in which only tags are available for editing

    class ArticleEditProxyForm(forms.ModelForm):
        class Meta:
            model = ArticleEditProxy
            fields = ['tags']
    class ArticleEditProxyAdmin(admin.ModelAdmin):
        list_display = ['title', 'tags']
        form = ArticleEditProxyForm
        readonly_fields = ['title', 'body']
    admin.site.register(ArticleEditProxy, ArticleEditProxyAdmin)
    


    Now, when you go to the admin panel, the user will be able to see the list of articles and will be able to change tags for any article, he will also see the title and contents of the article, but will not be able to change them.

    Another nuance. Access rights to objects of various models are implemented in the jung through objects of the Permission model. Reading is one Permission object, writing is another, another is deleting. Permission objects for new models are created at the time the command is run manage.py syncdb. If at the time of creating the proxy model your application was controlled through south, then Permission objects will not be created, south will not “notice” your proxy model, and the syncdb operation does not work with applications served by south .

    You will have to create a migration that will send the post_syncdb signal for your proxy model.

    class Migration(SchemaMigration):
        def forwards(self, orm):
            db.send_create_signal('myapp', ['ArticleEditProxy'])
    


    I learned the details of the migration hack on this blog.

    Also popular now: