Overriding methods in models of other developers

9 views
Skip to first unread message

אורי

unread,
Jul 27, 2019, 2:27:42 AM7/27/19
to django...@googlegroups.com
Django users,

I want to override def __str__ of models I'm using, but the models are maintained by other developers. I think the __str__ is only used by the admin interface. I found out that I can do something like this:

from django.contrib import admin
from django.contrib.sites.models import Site
from django.contrib.auth.models import Group

from friendship.models import Follow, Friend, FriendshipRequest, Block


class ReadOnlyModelAdmin(admin.ModelAdmin):
"""
ModelAdmin class that prevents modifications through the admin.

The changelist and the detail view work, but a 403 is returned
if one actually tries to edit an object.
"""
actions = None

# We cannot call super().get_fields(request, obj) because that method calls
# get_readonly_fields(request, obj), causing infinite recursion. Ditto for
# super().get_form(request, obj). So we assume the default ModelForm.
def get_readonly_fields(self, request, obj=None):
return self.fields or [f.name for f in self.model._meta.fields]

def has_add_permission(self, request):
return False

# Allow viewing objects but not actually changing them.
def has_change_permission(self, request, obj=None):
return (request.method in ['GET', 'HEAD'] and super().has_change_permission(request, obj))

def has_delete_permission(self, request, obj=None):
return False


admin.site.unregister(Site)
admin.site.register(Site, ReadOnlyModelAdmin)

admin.site.unregister(Group)
# admin.site.register(Group, ReadOnlyModelAdmin)

admin.site.unregister(Block)
admin.site.unregister(Follow)
admin.site.unregister(Friend)
admin.site.unregister(FriendshipRequest)
# admin.site.register(Block, ReadOnlyModelAdmin)
# admin.site.register(Follow, ReadOnlyModelAdmin)
admin.site.register(Friend, ReadOnlyModelAdmin)
admin.site.register(FriendshipRequest, ReadOnlyModelAdmin)


class Friend1(Friend):
def __str__(self):
return "User {} is friends with {}".format(self.to_user, self.from_user)


class FriendshipRequest1(FriendshipRequest):
def __str__(self):
return "Friendship request from user {} to {}".format(self.from_user, self.to_user)


Friend.__str__ = Friend1.__str__
FriendshipRequest.__str__ = FriendshipRequest1.__str__

But, is it possible override __str__ in a cleaner way? It seems to me not such a clean way to override a method (but it works). But I have to use the model itself, because there is a lot of code in the package I'm using that uses the model itself.

(We are using our own Block model which I think we developed before they developed a similar model. We are not using their Follow model too).

אורי

unread,
Jul 27, 2019, 3:49:22 AM7/27/19
to django...@googlegroups.com
Hi,

I had to change the following lines because tests failed:

class Friend1(object):

def __str__(self):
return "User {} is friends with {}".format(self.to_user, self.from_user)


class FriendshipRequest1(object):

def __str__(self):
return "Friendship request from user {} to {}".format(self.from_user, self.to_user)


Friend.__str__ = Friend1.__str__
FriendshipRequest.__str__ = FriendshipRequest1.__str__


Jani Tiainen

unread,
Jul 27, 2019, 6:44:43 AM7/27/19
to django...@googlegroups.com
You  can do that with proxy models which allows you to override and add methods.

Of course if there is a need to really modify original model it gets tricky.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CABD5YeHNUEozN0vg_M5Hz9QrCTUAzH--u9SHtPVeDvJ4ZgWeOA%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages