3

Here are my models

class Note():
    note = models.TextField(null=False, blank=False, editable=True)
    user = models.ForeignKey(to=User, null=True, blank=True)

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

And an inline I created this model to incorporate in any admin is below

class NoteInline(GenericTabularInline):
    model = Note
    extra = 0

What I need here is, I want to see all the current notes but don't want the logged in user to edit them. At the moment user can edit old and add new. So here is what I did,

class NoteInline(GenericTabularInline):
    model = Note
    extra = 0

    def get_readonly_fields(self, request, obj=None):
        if obj and 'change' in request.resolver_match.url_name:
            return ['note', 'user', ]
        else:
            return []

But now if user adds new note he sees a disabled (not editable) note text ares. However user can see old fields not editable.

How to implement this functionality?

Fahad Siddiqui
  • 1,829
  • 1
  • 19
  • 41
  • Perhaps something like this could work, where there's a different inline added for the "add" and "change" views? https://djangosnippets.org/snippets/3084/ – tdsymonds Aug 09 '17 at 15:18
  • 1
    This doesn't make the inline partially readonly and partially editable (new addition for notes inline). So here is what I did, splitting into two new inlines. Explained nicely here https://stackoverflow.com/a/28149575/1439913 – Fahad Siddiqui Aug 10 '17 at 09:15

1 Answers1

1

I am having the same inquiry.

However, I do not care if the fields in the inline are "read only" or not. I just do not want them changed once they are created.

For this purpose, I created a NoteForm in forms.py which raises a validation error if the instance has changed while it has initial data:

class NoteForm(forms.ModelForm):
    def clean(self):
        if self.has_changed() and self.initial:
            raise ValidationError(
                'You cannot change this inline',
                code='Forbidden'
            )
        return super().clean()

    class Meta(object):
        model = Note
        fields='__all__'

admin.py:

class NoteInline(GenericTabularInline):
    model = Note
    extra = 0
    form = NoteForm
raratiru
  • 8,748
  • 4
  • 73
  • 113