#382 closed defect (wontfix)
globals should show up in model methods and classes (like normal python classes)
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | minor | Keywords: | |
Cc: | brenocon@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I want to do this:
import re class Note(meta.Model): #... def __repr__(self): if re.search(...)
Unfortunately, "re" isn't present in the namespace. The following exception occurs:
File "c:\brendano\djblog\apps\blog\models\blog.py", line 25, in __repr__ if re.search(r'^\s*$', self.title): NameError: global name 're' is not defined
as a workaround I can just do "import re" inside the method. But the larger problem is, all module-level (global) variables don't appear inside any method namespaces.
myglobal = 5 class Note(meta.Model): #... def __repr__(self): print myglobal
also gives the same error. In fact, a manual "global myglobal" statement fails to make it work.
IMPORTANCE: so I guess the preferred django way of doing things is to make the model classes as sparse and declarative as possible. In that case the bug is a minor inconvenience.
SUSPECTED CAUSE: maybe a bug in the ModelBase metaclass?
SVN version: 541
Change History (7)
comment:1 by , 19 years ago
Severity: | normal → minor |
---|
comment:2 by , 19 years ago
I see. It's a bit confusing since that violates the way a python file usually works: you define module-level variables, then you can get at them inside other declarations in that file. I guess things are complex for django because of virtual modules... I can't think of how to make the system more like normal python in this regard.
comment:3 by , 19 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
See "Using module globals in models" on the DataModelPitfalls page.
comment:4 by , 19 years ago
Cc: | added |
---|---|
Resolution: | invalid |
Status: | closed → reopened |
Summary: | Module-level variables in model methods don't show up → globals should show up in model methods and classes (like normal python classes) |
Now with #122 implemented, models are starting to look like and behave more like standard python classes -- this is great! Ideally, you should be able to program all sorts of methods on a model class and use imports and global variables like normal.
Are there any design reasons not to have models work like this?
Sorry for reopening this, but it seems to me at least that this is the direction models ought to go -- I'd defintiely like to see that before using django intensively for any big projects, myself.
comment:5 by , 19 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
I can't fathom why you would avoid using Django intensively because of a little thing like this...
Yes, there's a design reason for custom model methods functions not having access to globals from the model module. A model module can define *multiple* model classes, and there's too much "stuff" in a model module for it to make sense to give *all* custom methods access to *all* globals. It's just too...messy.
comment:6 by , 19 years ago
sorry, i should say -- it's one of those things i'd try to fix if I started using it :) If I write 10 methods on a class, and have to do those imports inside each class, I just know I'm dumb and will forget things or forget to update code when things rename, and things will breaking...
a python file can define multiple classes too, and those classes all have access to globals defined in that file.
comment:7 by , 19 years ago
class Note(meta.Model): _m_c = {} from types import ModuleType for k,v in globals().items(): if isinstance(v, ModuleType): _m_c[k] = v module_constants = _m_c
Might save you some trouble. Or you can subclass models Meta class from MyMeta which does that for you.
That's by design -- whilst
re
is present in your model module, it's not automatically exposed to each virtual module generated from the model classes. To insert it into those, you need to definemodule_constants
: