Opened 3 weeks ago

Last modified 3 weeks ago

#29385 new Cleanup/optimization

Make ModelDetailView show model properties

Reported by: Bostjan Kaluza Owned by: nobody
Component: contrib.admindocs Version: 2.0
Severity: Normal Keywords:
Cc: Nat S Dunn Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Model properties (like one below) do not show in the admin documentation:

  class MyModel(models.Model):
      name = models.CharField(max_length=200)
      public = models.BooleanField(default=False)
      date_approved = models.DateTimeField(null=True, blank=True)

      @property
      def status(self):
      """
        returns the status of object
      """
      if self.date_approved and self.public:
        return "Public"
      elif self.public:
        return "Pending Approval"
      else:
        return "Private"

Change History (4)

comment:1 Changed 3 weeks ago by Bostjan Kaluza

It seem easy to fix. In file django/contrib/admindocs/views.py method ModelDetailView.get_context_data gathers model methods, but skips the properties as they are not methods. So we need to (1) add properties to the condition and (2) append the property to the list of fields.

# Gather model methods.
for func_name, func in model.__dict__.items():
    #
    # CHANGE 1: add isinstance(func, property) to the condition
    #
    # if inspect.isfunction(func): # old line
    if inspect.isfunction(func) or isinstance(func, property):
        try:
            for exclude in MODEL_METHODS_EXCLUDE:
                if func_name.startswith(exclude):
                    raise StopIteration
        except StopIteration:
            continue
        verbose = func.__doc__
        if verbose:
            verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.model_name)

        #
        # CHANGE 2: If this is a property, show it as a 'field'
        #
        if isinstance(func, property):
            fields.append({
                'name': func_name,
                'data_type': get_return_data_type(func_name),
                'verbose': verbose or '',
            })
        # Else if a method has no arguments, show it as a 'field', otherwise
        # as a 'method with arguments'.
        elif func_has_no_args(func) and not func_accepts_kwargs(func) and not func_accepts_var_args(func):
            fields.append({
                'name': func_name,
                'data_type': get_return_data_type(func_name),
                'verbose': verbose or '',
            })
        else:
            arguments = get_func_full_args(func)
            # Join arguments with ', ' and in case of default value,
            # join it with '='. Use repr() so that strings will be
            # correctly displayed.
            print_arguments = ', '.join([
                '='.join(list(arg_el[:1]) + [repr(el) for el in arg_el[1:]])
                for arg_el in arguments
            ])
            methods.append({
                'name': func_name,
                'arguments': print_arguments,
                'verbose': verbose or '',
            })

comment:2 Changed 3 weeks ago by Bostjan Kaluza

comment:3 Changed 3 weeks ago by Tim Graham

Has patch: set
Patch needs improvement: set
Summary: Admindocs doesn't show model propertiesMake ModelDetailView show model properties
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

A test and documentation update are also required.

comment:4 Changed 3 weeks ago by Nat S Dunn

Cc: Nat S Dunn added
Note: See TracTickets for help on using tickets.
Back to Top