Opened 7 years ago

Last modified 8 weeks ago

#12096 new New feature

Model fields are not accessible as attributes of the model class

Reported by: sejo Owned by:
Component: Database layer (models, ORM) Version: 1.1
Severity: Normal Keywords: model, docstrings, attributes
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using attribute docstrings in my models they will never be picked up by doctools as the attributes disappear top level from the model.
This makes me to keep separate documentation and code for djagios.

Change History (10)

comment:1 Changed 7 years ago by sejo

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 7 years ago by jacob

  • Owner changed from nobody to jacob
  • Status changed from new to assigned

comment:3 Changed 7 years ago by jacob

  • Triage Stage changed from Unreviewed to Accepted

comment:4 Changed 7 years ago by jacob

This is actually because ModelClass.field raises AttributeError from the descriptor. I've been wanting to stop that, anyway -- it ought to just return the Field object.

comment:5 Changed 5 years ago by julien

  • Severity set to Normal
  • Type set to Bug

comment:6 Changed 4 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:7 Changed 4 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:8 Changed 3 years ago by aaugustin

  • Component changed from Core (Other) to Database layer (models, ORM)

comment:9 Changed 8 months ago by timgraham

  • Owner jacob deleted
  • Status changed from assigned to new
  • Summary changed from model attributes are not set toplevel which causes doctools to miss the attribute docstrings to Model fields are not accessible as attributes of the model class
  • Type changed from Bug to New feature

I'm not sure what the implementation should look like. It seems that Jacob's comment about "ModelClass.field raises AttributeError is obsolete.

comment:10 Changed 8 weeks ago by sephii

To get this to work we need to change some low-level stuff since model fields are stripped out by the metaclass to be put in Model._meta. Since Sphinx's autodoc module allows to manually add members to a class I think it would be better to do in manually than trying to change the way Django models are constructed.

Anyway, I came up with the following code that makes Sphinx's autodoc work for Django models. It is very hackish and unsurprisingly makes some tests fail, so I'm just putting this here for the record in case anyone would want to take that over someday.

class ModelBase(type):
    def __getattr__(self, attr):
        if attr == '_meta':
            raise AttributeError(attr)

        try:
            return self._meta.get_field(attr)
        except FieldDoesNotExist:
            raise AttributeError(attr)

    @property
    def __dict__(self):
        try:
            model_dict = {
                f.name: f for f in self._meta.get_fields()
            }
        except AppRegistryNotReady:
            model_dict = {}

        model_dict.update(super(ModelBase, self).__dict__)
        return model_dict

    # Rest of ModelBase code...
Note: See TracTickets for help on using tickets.
Back to Top