From 7f2e6dd4fa2df65f2b0fc206e0e0b13f6bb3043a Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 2 Oct 2011 01:21:03 +0200 Subject: [PATCH] Tidying up the admin interface by adding more verbose and helpful names to database fields as well as adding more help texts. The ObjectAdmin still gives tracebacks. --- src/comms/admin.py | 35 +++++++++++++++++++-------- src/comms/models.py | 50 +++++++++++++++++++++++---------------- src/help/admin.py | 8 ++++++- src/help/models.py | 11 +++++---- src/objects/admin.py | 6 +++-- src/objects/models.py | 20 +++++++++------- src/players/admin.py | 22 ++++++++++++++--- src/players/models.py | 11 +++++---- src/scripts/admin.py | 6 +++++ src/scripts/models.py | 18 +++++++------- src/typeclasses/models.py | 30 +++++++++++------------ 11 files changed, 137 insertions(+), 80 deletions(-) diff --git a/src/comms/admin.py b/src/comms/admin.py index 721dd6c5f5..14e923aaa1 100644 --- a/src/comms/admin.py +++ b/src/comms/admin.py @@ -10,29 +10,44 @@ class MsgAdmin(admin.ModelAdmin): list_display = ('id', 'db_date_sent', 'db_sender', 'db_receivers', 'db_channels', 'db_message', 'db_lock_storage') list_display_links = ("id",) ordering = ["db_date_sent", 'db_sender', 'db_receivers', 'db_channels'] - readonly_fields = ['db_message', 'db_sender', 'db_receivers', 'db_channels'] + #readonly_fields = ['db_message', 'db_sender', 'db_receivers', 'db_channels'] search_fields = ['id', '^db_date_sent', '^db_message'] save_as = True save_on_top = True list_select_related = True + #admin.site.register(Msg, MsgAdmin) class PlayerChannelConnectionInline(admin.TabularInline): model = PlayerChannelConnection + fieldsets = ( + (None, { + 'fields':(('db_player', 'db_channel')), + 'classes':('collapse',)}),) max_num = 1 -class ExternalChannelConnectionInline(admin.TabularInline): +class ExternalChannelConnectionInline(admin.StackedInline): model = ExternalChannelConnection + fieldsets = ( + (None, { + 'fields':(('db_is_enabled','db_external_key', 'db_channel'), 'db_external_send_code', 'db_external_config'), + 'classes':('collapse',) + }),) max_num = 1 class ChannelAdmin(admin.ModelAdmin): - inlines = [PlayerChannelConnectionInline, ExternalChannelConnectionInline] - # list_display = ('id', 'db_key', 'db_desc', 'db_aliases', 'db_keep_log', 'db_lock_storage') - # list_display_links = ("id", 'db_key') - # ordering = ["db_key"] - # search_fields = ['id', 'db_key', 'db_aliases'] - # save_as = True - # save_on_top = True - # list_select_related = True + inlines = (PlayerChannelConnectionInline, ExternalChannelConnectionInline) + + list_display = ('id', 'db_key', 'db_desc', 'db_aliases', 'db_keep_log', 'db_lock_storage') + list_display_links = ("id", 'db_key') + ordering = ["db_key"] + search_fields = ['id', 'db_key', 'db_aliases'] + save_as = True + save_on_top = True + list_select_related = True + fieldsets = ( + (None, {'fields':(('db_key', 'db_aliases', 'db_desc'),'db_lock_storage', 'db_keep_log')}), + ) + admin.site.register(Channel, ChannelAdmin) # class PlayerChannelConnectionAdmin(admin.ModelAdmin): diff --git a/src/comms/models.py b/src/comms/models.py index e6308b4cdf..0d13d666d1 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -88,23 +88,27 @@ class Msg(SharedMemoryModel): # named same as the field, but withtout the db_* prefix. # There must always be one sender of the message. - db_sender = models.ForeignKey("players.PlayerDB", related_name='sender_set', null=True) + db_sender = models.ForeignKey("players.PlayerDB", related_name='sender_set', null=True, verbose_name='sender') # in the case of external senders, no Player object might be available - db_sender_external = models.CharField(max_length=255, null=True, blank=True) + db_sender_external = models.CharField('external sender', max_length=255, null=True, blank=True, + help_text="identifier for external sender, for example a sender over an IRC connection (i.e. someone who doesn't have an exixtence in-game).") # The destination objects of this message. Stored as a # comma-separated string of object dbrefs. Can be defined along # with channels below. - db_receivers = models.CharField(max_length=255, null=True, blank=True) + db_receivers = models.CharField('receivers', max_length=255, null=True, blank=True, + help_text='comma-separated list of object dbrefs this message is aimed at.') # The channels this message was sent to. Stored as a # comma-separated string of channel dbrefs. A message can both # have channel targets and destination objects. - db_channels = models.CharField(max_length=255, null=True, blank=True) + db_channels = models.CharField('channels', max_length=255, null=True, blank=True, + help_text='comma-separated list of channel dbrefs this message is aimed at.') # The actual message and a timestamp. The message field # should itself handle eventual headers etc. - db_message = models.TextField() - db_date_sent = models.DateTimeField(editable=False, auto_now_add=True) + db_message = models.TextField('messsage') + db_date_sent = models.DateTimeField('date sent', editable=False, auto_now_add=True) # lock storage - db_lock_storage = models.CharField(max_length=512, blank=True) + db_lock_storage = models.CharField('locks', max_length=512, blank=True, + help_text='access locks on this message.') # These are settable by senders/receivers/channels respectively. # Stored as a comma-separated string of dbrefs. Can be used by the # game to mask out messages from being visible in the archive (no @@ -125,7 +129,6 @@ class Msg(SharedMemoryModel): class Meta: "Define Django meta options" verbose_name = "Message" - verbose_name_plural = "Messages" # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using @@ -392,21 +395,25 @@ class Channel(SharedMemoryModel): # named same as the field, but withtout the db_* prefix. # unique identifier for this channel - db_key = models.CharField(max_length=255, unique=True) + db_key = models.CharField('key', max_length=255, unique=True) # optional description of channel - db_desc = models.CharField(max_length=80, blank=True, null=True) + db_desc = models.CharField('description', max_length=80, blank=True, null=True) # aliases for the channel. These are searched by cmdhandler # as well to determine if a command is the name of a channel. # Several aliases are separated by commas. - db_aliases = models.CharField(max_length=255) + db_aliases = models.CharField('aliases', max_length=255) # Whether this channel should remember its past messages db_keep_log = models.BooleanField(default=True) # Storage of lock definitions - db_lock_storage = models.CharField(max_length=512, blank=True) + db_lock_storage = models.CharField('locks', max_length=512, blank=True) # Database manager objects = managers.ChannelManager() + class Meta: + "Define Django meta options" + verbose_name = "Channel" + def __init__(self, *args, **kwargs): SharedMemoryModel.__init__(self, *args, **kwargs) self.locks = LockHandler(self) @@ -612,9 +619,9 @@ class PlayerChannelConnection(SharedMemoryModel): """ # Player connected to a channel - db_player = models.ForeignKey("players.PlayerDB") + db_player = models.ForeignKey("players.PlayerDB", verbose_name='player') # Channel the player is connected to - db_channel = models.ForeignKey(Channel) + db_channel = models.ForeignKey(Channel, verbose_name='channel') # Database manager objects = managers.PlayerChannelConnectionManager() @@ -667,22 +674,25 @@ class ExternalChannelConnection(SharedMemoryModel): that connection. """ # evennia channel connecting to - db_channel = models.ForeignKey(Channel) + db_channel = models.ForeignKey(Channel, verbose_name='channel', + help_text='which channel this connection is tied to.') # external connection identifier - db_external_key = models.CharField(max_length=128) + db_external_key = models.CharField('external key', max_length=128, + help_text='external connection identifier, used by calling protocol.') # eval-code to use when the channel tries to send a message # to the external protocol. - db_external_send_code = models.TextField(blank=True) + db_external_send_code = models.TextField('executable code', blank=True, + help_text='this is a custom snippet of Python code to connect the external protocol to the in-game channel.') # custom config for the connection - db_external_config = models.TextField(blank=True) + db_external_config = models.TextField('external config', blank=True, + help_text='configuration options on form understood by connection.') # activate the connection - db_is_enabled = models.BooleanField(default=True) + db_is_enabled = models.BooleanField('is enabled', default=True, help_text='turn on/off the connection.') objects = managers.ExternalChannelConnectionManager() class Meta: verbose_name = "External Channel Connection" - verbose_name_plural = "External Channel Connections" def __str__(self): return "%s <-> external %s" % (self.channel.key, self.db_external_key) diff --git a/src/help/admin.py b/src/help/admin.py index b4a607bd08..62014cd278 100644 --- a/src/help/admin.py +++ b/src/help/admin.py @@ -2,11 +2,17 @@ from django.contrib import admin from src.help.models import HelpEntry class HelpEntryAdmin(admin.ModelAdmin): - list_display = ('id', 'db_key', 'db_help_category') + + list_display = ('id', 'db_key', 'db_help_category', 'db_lock_storage') list_display_links = ('id', 'db_key') search_fields = ['^db_key', 'db_entrytext'] ordering = ['db_help_category', 'db_key'] save_as = True save_on_top = True list_select_related = True + fieldsets = ( + (None, {'fields':(('db_key', 'db_help_category'), 'db_entrytext', 'db_lock_storage'), + 'description':"Sets a Help entry. Set lock to view:all() unless you want to restrict it."}),) + + admin.site.register(HelpEntry, HelpEntryAdmin) diff --git a/src/help/models.py b/src/help/models.py index d6dff849d4..184111fa9b 100644 --- a/src/help/models.py +++ b/src/help/models.py @@ -42,15 +42,16 @@ class HelpEntry(SharedMemoryModel): # named same as the field, but withtout the db_* prefix. # title of the help - db_key = models.CharField(max_length=255, unique=True) + db_key = models.CharField('help key', max_length=255, unique=True, help_text='Key to search for.') # help category - db_help_category = models.CharField(max_length=255, default="General") + db_help_category = models.CharField("help category", max_length=255, default="General", + help_text='Organizes help entries in lists.') # the actual help entry text, in any formatting. - db_entrytext = models.TextField(blank=True) + db_entrytext = models.TextField('help entry', blank=True, help_text='The main body of help text.') # a string of permissionstrings, separated by commas. - db_permissions = models.CharField(max_length=255, blank=True) + db_permissions = models.CharField('permissions', max_length=255, blank=True) # lock string storage - db_lock_storage = models.CharField(max_length=512, blank=True) + db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text='Normally view:all().') # (deprecated, only here to allow MUX helpfile load (don't use otherwise)). # TODO: remove this when not needed anymore. db_staff_only = models.BooleanField(default=False) diff --git a/src/objects/admin.py b/src/objects/admin.py index 2e082cf49b..b51ddcbe80 100644 --- a/src/objects/admin.py +++ b/src/objects/admin.py @@ -11,13 +11,15 @@ class ObjAttributeInline(admin.TabularInline): fields = ('db_key', 'db_value') max_num = 1 -class ObjectDBAdmin(admin.ModelAdmin): - inlines = [ObjAttributeInline] +class ObjectDBAdmin(admin.ModelAdmin): list_display = ('id', 'db_key', 'db_location', 'db_player', 'db_typeclass_path') list_display_links = ('id', 'db_key') ordering = ['db_player', 'db_typeclass_path', 'id'] search_fields = ['^db_key', 'db_typeclass_path'] + save_as = True save_on_top = True list_select_related = True + inlines = [ObjAttributeInline] + admin.site.register(ObjectDB, ObjectDBAdmin) diff --git a/src/objects/models.py b/src/objects/models.py index d57c6f3922..d97b01c8ff 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -63,8 +63,8 @@ class Alias(SharedMemoryModel): is so as to allow for effective global searches also by alias. """ - db_key = models.CharField(max_length=255) - db_obj = models.ForeignKey("ObjectDB") + db_key = models.CharField('alias', max_length=255) + db_obj = models.ForeignKey("ObjectDB", verbose_name='object') class Meta: "Define Django meta options" @@ -92,12 +92,12 @@ class ObjectNick(TypeNick): obj - match against object searches channel - used to store own names for channels """ - db_obj = models.ForeignKey("ObjectDB") + db_obj = models.ForeignKey("ObjectDB", verbose_name='object') class Meta: "Define Django meta options" verbose_name = "Nickname for Objects" - verbose_name_plural = "Nicknames Objects" + verbose_name_plural = "Nicknames for Objects" unique_together = ("db_nick", "db_type", "db_obj") class ObjectNickHandler(TypeNickHandler): @@ -163,20 +163,22 @@ class ObjectDB(TypedObject): # but withtout the db_* prefix. # If this is a character object, the player is connected here. - db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True) + db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player', + help_text='a Player connected to this object, if any.') # The location in the game world. Since this one is likely # to change often, we set this with the 'location' property # to transparently handle Typeclassing. db_location = models.ForeignKey('self', related_name="locations_set", - blank=True, null=True) + blank=True, null=True, verbose_name='game location') # a safety location, this usually don't change much. db_home = models.ForeignKey('self', related_name="homes_set", - blank=True, null=True) + blank=True, null=True, verbose_name='home location') # destination of this object - primarily used by exits. db_destination = models.ForeignKey('self', related_name="destinations_set", - blank=True, null=True) + blank=True, null=True, verbose_name='destination', + help_text='a destination, used only by exit objects.') # database storage of persistant cmdsets. - db_cmdset_storage = models.CharField(max_length=255, null=True) + db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True) # Database manager objects = ObjectManager() diff --git a/src/players/admin.py b/src/players/admin.py index eea2abd52f..6460292fdd 100644 --- a/src/players/admin.py +++ b/src/players/admin.py @@ -16,8 +16,12 @@ class PlayerInline(admin.TabularInline): model = PlayerDB class UserAdmin(BaseUserAdmin): - inlines = [PlayerInline] - #fields = ('username', 'email', "is_staff", "is_superuser") + add_fieldsets = ( + (None, + {'fields': ('username', 'email', 'password1', 'password2', ('is_staff', 'is_superuser')), + 'description':'Note that whereas Player name supports spaces, This User field does not!'},), + ) + admin.site.register(User, UserAdmin) # class PlayerAttributeAdmin(admin.ModelAdmin): @@ -26,11 +30,17 @@ admin.site.register(User, UserAdmin) class PlayerAttributeInline(admin.TabularInline): model = PlayerAttribute - fields = ('db_key', 'db_value') + #fields = ('db_key', 'db_value') + fieldsets = ( + ("Attributes", + {'fields' : (('db_key', 'db_value')), + 'classes' : ('wide',)}), ) + max_num = 1 class PlayerDBAdmin(admin.ModelAdmin): inlines = [PlayerAttributeInline] + list_display = ('id', 'db_key', 'user', 'db_permissions', 'db_typeclass_path') list_display_links = ('id', 'db_key') ordering = ['db_key', 'db_typeclass_path'] @@ -38,4 +48,10 @@ class PlayerDBAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True + fieldsets = ( + (None, + {'fields' : (('db_key', 'db_typeclass_path'), 'user', ('db_permissions','db_lock_storage'), 'db_obj'), + 'description': 'To create a new Player, a User object must also be created and/or assigned.', + 'classes' : ('wide', 'extrapretty')}),) + admin.site.register(PlayerDB, PlayerDBAdmin) diff --git a/src/players/models.py b/src/players/models.py index 04f93a31f5..d6c7153892 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -72,7 +72,6 @@ class PlayerAttribute(Attribute): class Meta: "Define Django meta options" verbose_name = "Player Attribute" - verbose_name_plural = "Player Attributes" #------------------------------------------------------------ # @@ -89,7 +88,7 @@ class PlayerNick(TypeNick): obj - match against object searches channel - used to store own names for channels """ - db_obj = models.ForeignKey("PlayerDB") + db_obj = models.ForeignKey("PlayerDB", verbose_name="player") class Meta: "Define Django meta options" @@ -148,19 +147,21 @@ class PlayerDB(TypedObject): # this is the one-to-one link between the customized Player object and # this profile model. It is required by django. - user = models.ForeignKey(User, unique=True) + user = models.ForeignKey(User, unique=True, + help_text="The User object holds django-related authentication. Each Player must have a unique User account linked to them at all times.") # the in-game object connected to this player (if any). # Use the property 'obj' to access. - db_obj = models.ForeignKey("objects.ObjectDB", null=True) + db_obj = models.ForeignKey("objects.ObjectDB", null=True, verbose_name="character", help_text='In-game object (optional).') # database storage of persistant cmdsets. - db_cmdset_storage = models.CharField(max_length=255, null=True) + db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True) # Database manager objects = manager.PlayerManager() class Meta: app_label = 'players' + verbose_name = 'Player' def __init__(self, *args, **kwargs): "Parent must be initiated first" diff --git a/src/scripts/admin.py b/src/scripts/admin.py index 804eada972..6aa84d9e30 100644 --- a/src/scripts/admin.py +++ b/src/scripts/admin.py @@ -20,4 +20,10 @@ class ScriptDBAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True + + fieldsets = ( + (None, { + 'fields':(('db_key', 'db_typeclass_path'), 'db_interval', 'db_repeats', 'db_start_delay', 'db_persistent', 'db_obj')}), + ) + admin.site.register(ScriptDB, ScriptDBAdmin) diff --git a/src/scripts/models.py b/src/scripts/models.py index b44a276035..06e1b97d31 100644 --- a/src/scripts/models.py +++ b/src/scripts/models.py @@ -37,7 +37,7 @@ from src.scripts.manager import ScriptManager class ScriptAttribute(Attribute): "Attributes for ScriptDB objects." - db_obj = models.ForeignKey("ScriptDB") + db_obj = models.ForeignKey("ScriptDB", verbose_name='script') class Meta: "Define Django meta options" @@ -88,19 +88,20 @@ class ScriptDB(TypedObject): # db_key, db_typeclass_path, db_date_created, db_permissions # optional description. - db_desc = models.CharField(max_length=255, blank=True) + db_desc = models.CharField('desc', max_length=255, blank=True) # A reference to the database object affected by this Script, if any. - db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True) + db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True, verbose_name='scripted object', + help_text='the object to store this script on, if not a global script.') # how often to run Script (secs). -1 means there is no timer - db_interval = models.IntegerField(default=-1) + db_interval = models.IntegerField('interval', default=-1, help_text='how often to repeat script, in seconds. -1 means off.') # start script right away or wait interval seconds first - db_start_delay = models.BooleanField(default=False) + db_start_delay = models.BooleanField('start delay', default=False, help_text='pause interval seconds before starting.') # how many times this script is to be repeated, if interval!=0. - db_repeats = models.IntegerField(default=0) + db_repeats = models.IntegerField('number of repeats', default=0, help_text='0 means off.') # defines if this script should survive a reboot or not - db_persistent = models.BooleanField(default=False) + db_persistent = models.BooleanField('survive server reboot', default=False) # defines if this script has already been started in this session - db_is_active = models.BooleanField(default=False) + db_is_active = models.BooleanField('script active', default=False) # Database manager objects = ScriptManager() @@ -108,7 +109,6 @@ class ScriptDB(TypedObject): class Meta: "Define Django meta options" verbose_name = "Script" - verbose_name_plural = "Scripts" # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index e6f8436f89..9ba1fe64da 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -200,16 +200,16 @@ class Attribute(SharedMemoryModel): # These databse fields are all set using their corresponding properties, # named same as the field, but withtout the db_* prefix. - db_key = models.CharField(max_length=255) + db_key = models.CharField('key', max_length=255) # access through the value property - db_value = models.TextField(blank=True, null=True) + db_value = models.TextField('value', blank=True, null=True) # Lock storage - db_lock_storage = models.CharField(max_length=512, blank=True) + db_lock_storage = models.CharField('locks', max_length=512, blank=True) # references the object the attribute is linked to (this is set # by each child class to this abstact class) db_obj = None # models.ForeignKey("RefencedObject") # time stamp - db_date_created = models.DateTimeField(editable=False, auto_now_add=True) + db_date_created = models.DateTimeField('date_created',editable=False, auto_now_add=True) # Database manager objects = managers.AttributeManager() @@ -224,8 +224,7 @@ class Attribute(SharedMemoryModel): class Meta: "Define Django meta options" abstract = True - verbose_name = "Evennia Attribute" - verbose_name_plural = "Evennia Attributes" + verbose_name = "Evennia Attribute" # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using @@ -449,16 +448,16 @@ class TypeNick(SharedMemoryModel): channel - used to store own names for channels """ - db_nick = models.CharField(max_length=255, db_index=True) # the nick - db_real = models.TextField() # the aliased string - db_type = models.CharField(default="inputline", max_length=16, null=True, blank=True) # the type of nick + db_nick = models.CharField('nickname',max_length=255, db_index=True, help_text='the alias') + db_real = models.TextField('realname', help_text='the original string to match and replace.') + db_type = models.CharField('nick type',default="inputline", max_length=16, null=True, blank=True, + help_text="the nick type describes when the engine tries to do nick-replacement. Common options are 'inputline','player','obj' and 'channel'. Inputline checks everything being inserted, whereas the other cases tries to replace in various searches or when posting to channels.") db_obj = None #models.ForeignKey("ObjectDB") class Meta: "Define Django meta options" abstract = True verbose_name = "Nickname" - verbose_name_plural = "Nicknames" unique_together = ("db_nick", "db_type", "db_obj") class TypeNickHandler(object): @@ -543,16 +542,16 @@ class TypedObject(SharedMemoryModel): # Main identifier of the object, for searching. Can also # be referenced as 'name'. - db_key = models.CharField(max_length=255) + db_key = models.CharField('key', max_length=255) # This is the python path to the type class this object is tied to # (the type class is what defines what kind of Object this is) - db_typeclass_path = models.CharField(max_length=255, null=True) + db_typeclass_path = models.CharField('typeclass', max_length=255, null=True, help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") # Creation date - db_date_created = models.DateTimeField(editable=False, auto_now_add=True) + db_date_created = models.DateTimeField('creation date', editable=False, auto_now_add=True) # Permissions (access these through the 'permissions' property) - db_permissions = models.CharField(max_length=255, blank=True) + db_permissions = models.CharField('permissions', max_length=255, blank=True, help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Normal players use 'Players' by default.") # Lock storage - db_lock_storage = models.CharField(max_length=512, blank=True) + db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Take a look at other Players to set this to a valid string.") # Database manager objects = managers.TypedObjectManager() @@ -573,7 +572,6 @@ class TypedObject(SharedMemoryModel): """ abstract = True verbose_name = "Evennia Database Object" - verbose_name_plural = "Evennia Database Objects" ordering = ['-db_date_created', 'id', 'db_typeclass_path', 'db_key'] # Wrapper properties to easily set database fields. These are