From e1b4e6f7bc208328da423509a758c976579f9323 Mon Sep 17 00:00:00 2001 From: Johnny Date: Wed, 17 Oct 2018 22:52:06 +0000 Subject: [PATCH] Renames all URL methods to web_*, moves to TypedObject model. --- evennia/accounts/accounts.py | 37 --------- evennia/accounts/tests.py | 6 +- evennia/objects/objects.py | 46 ----------- evennia/typeclasses/models.py | 145 ++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 86 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 6631911dc8..2c33e5c1f8 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -14,9 +14,7 @@ instead for most things). import time from django.conf import settings from django.contrib.auth import password_validation -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError -from django.urls import reverse from django.utils import timezone from evennia.typeclasses.models import TypeclassBase from evennia.accounts.manager import AccountManager @@ -191,41 +189,6 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): @lazy_property def sessions(self): return AccountSessionHandler(self) - - def get_absolute_url(self): - """ - Returns the canonical URL for an Account. - - To callers, this method should appear to return a string that can be - used to refer to the object over HTTP. - - https://docs.djangoproject.com/en/2.1/ref/models/instances/#get-absolute-url - """ - try: return reverse('account-detail', kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_delete_url(self): - """ - Returns the canonical URL to the page that allows deleting an object. - - """ - try: return reverse('account-delete', kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_update_url(self): - """ - Returns the canonical URL to the page that allows updating an object. - - """ - try: return reverse('account-update', kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_admin_url(self): - """ - Returns a link to this object's entry within the Django Admin panel. - """ - content_type = ContentType.objects.get_for_model(self.__class__) - return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) # session-related methods diff --git a/evennia/accounts/tests.py b/evennia/accounts/tests.py index 4d941782ad..fbf976d644 100644 --- a/evennia/accounts/tests.py +++ b/evennia/accounts/tests.py @@ -64,14 +64,14 @@ class TestDefaultAccount(TestCase): "Get URL for account detail page on website" self.account = create.create_account("TestAccount%s" % randint(100000, 999999), email="test@test.com", password="testpassword", typeclass=DefaultAccount) - self.assertTrue(self.account.get_absolute_url()) + self.assertTrue(self.account.web_detail_url()) def test_admin_url(self): "Get object's URL for access via Admin pane" self.account = create.create_account("TestAccount%s" % randint(100000, 999999), email="test@test.com", password="testpassword", typeclass=DefaultAccount) - self.assertTrue(self.account.get_admin_url()) - self.assertTrue(self.account.get_admin_url() != '#') + self.assertTrue(self.account.web_admin_url()) + self.assertTrue(self.account.web_admin_url() != '#') def test_password_validation(self): "Check password validators deny bad passwords" diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 71ccb28f77..027e8ff47f 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -329,52 +329,6 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): self.aliases.add(singular, category="plural_key") return singular, plural - def get_url_prefix(self): - """ - Derives the object name from the class name. - - i.e. 'DefaultAccount' = 'default-account', 'Character' = 'character' - """ - klass = self.__class__.__name__ - terms = [x.lower() for x in re.split('([A-Z][a-z]+)', klass) if x] - return slugify(' '.join(terms)) - - def get_absolute_url(self): - """ - Returns the canonical URL to view an object. - - To callers, this method should appear to return a string that can be - used to refer to the object over HTTP. - - https://docs.djangoproject.com/en/2.1/ref/models/instances/#get-absolute-url - """ - try: return reverse('%s-detail' % self.get_url_prefix(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_delete_url(self): - """ - Returns the canonical URL to the page that allows deleting an object. - - """ - try: return reverse('%s-delete' % self.get_url_prefix(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_update_url(self): - """ - Returns the canonical URL to the page that allows updating an object. - - """ - try: return reverse('%s-update' % self.get_url_prefix(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) - except: return '#' - - def get_admin_url(self): - """ - Returns a link to this object's entry within the Django Admin panel. - - """ - content_type = ContentType.objects.get_for_model(self.__class__) - return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) - def search(self, searchdata, global_search=False, use_nicks=True, diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index c156aa2ac6..098606b53c 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -31,9 +31,12 @@ from django.db.models import signals from django.db.models.base import ModelBase from django.db import models +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.conf import settings +from django.urls import reverse from django.utils.encoding import smart_str +from django.utils.text import slugify from evennia.typeclasses.attributes import Attribute, AttributeHandler, NAttributeHandler from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler @@ -733,3 +736,145 @@ class TypedObject(SharedMemoryModel): """ pass + + # + # Web/Django methods + # + + def web_admin_url(self): + """ + Returns the URI path for the Django Admin page for this object. + + ex. Account#1 = '/admin/accounts/accountdb/1/change/' + + Returns: + path (str): URI path to Django Admin page for object. + + """ + content_type = ContentType.objects.get_for_model(self.__class__) + return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) + + @classmethod + def web_create_url(cls): + """ + Returns the URI path for a View that allows users to create new + instances of this object. + + ex. Chargen = '/characters/create/' + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-create' would be referenced by this method. + + ex. + url(r'characters/create/', ChargenView.as_view(), name='character-create') + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can create new objects is the + developer's responsibility. + + Returns: + path (str): URI path to object creation page, if defined. + + """ + try: return reverse('%s-create' % cls._meta.verbose_name.lower()) + except: return '#' + + def web_detail_url(self): + """ + Returns the URI path for a View that allows users to view details for + this object. + + ex. Oscar (Character) = '/characters/oscar/1/' + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-detail' would be referenced by this method. + + ex. + url(r'characters/(?P[\w\d\-]+)/(?P[0-9]+)/$', CharDetailView.as_view(), name='character-detail') + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can view this object is the developer's + responsibility. + + Returns: + path (str): URI path to object detail page, if defined. + + """ + try: return reverse('%s-detail' % self._meta.verbose_name.lower(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) + except: return '#' + + def web_update_url(self): + """ + Returns the URI path for a View that allows users to update this + object. + + ex. Oscar (Character) = '/characters/oscar/1/change/' + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-update' would be referenced by this method. + + ex. + url(r'characters/(?P[\w\d\-]+)/(?P[0-9]+)/change/$', CharUpdateView.as_view(), name='character-update') + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can modify objects is the developer's + responsibility. + + Returns: + path (str): URI path to object update page, if defined. + + """ + try: return reverse('%s-update' % self._meta.verbose_name.lower(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) + except: return '#' + + def web_delete_url(self): + """ + Returns the URI path for a View that allows users to delete this object. + + ex. Oscar (Character) = '/characters/oscar/1/delete/' + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-detail' would be referenced by this method. + + ex. + url(r'characters/(?P[\w\d\-]+)/(?P[0-9]+)/delete/$', CharDeleteView.as_view(), name='character-delete') + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can delete this object is the developer's + responsibility. + + Returns: + path (str): URI path to object deletion page, if defined. + + """ + try: return reverse('%s-delete' % self._meta.verbose_name.lower(), kwargs={'pk': self.pk, 'slug': slugify(self.name)}) + except: return '#' + + def get_absolute_url(self): + """ + Django construct; used by Django Sites framework and within the Admin + panel for reverse linking to the object detail page. + + https://docs.djangoproject.com/en/2.1/ref/models/instances/#get-absolute-url + + Returns: + path (str): URI path to object detail page, if defined. + + """ + return self.web_detail_url() \ No newline at end of file