class TutorialAdmin(admin.ModelAdmin):
fields...
class Media:
js = ['/paths/...',]
I would like the ability to selectively override js. I've added a
"use_editor" boolean to the Tutorial model. The question is, how can I
detect whether the current instance has that bool set? I'd like to end
up with something like:
class Media:
if self.use_editor:
js = ['/paths',]
else:
js = ''
But can't find a way to make this work. Anyone have a working sample?
Thanks.
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
> And in the class where you keep use_editor:
>
> def get_path(self)
> if self.use_editor:
> return path1
> else:
> return path2
>
>
This is a cool idea, but unfortunately throws me back to the original
problem - the class in Admin.py doesn't know how to get to attributes
on the model it references. So if I do:
class Media:
js = get_path()
I get: "name 'get_path' is not defined".
If I do:
js = Tutorial.get_path()
I get: "unbound method get_editor_path() must be called with Tutorial
instance as first argument (got nothing instead)"
If I do:
js = Tutorial.get_path(self)
I get: "name 'self' is not defined"
Which is exactly the same problem as when I tried to access the field
directly. Seems like the core of the problem is that for some reason
"self" is not recognized from within admin.py classes.
Thanks for any tips on this.
Scot
--
On Mar 24, 12:05 pm, Firat Can Basarir <firatcanbasa...@gmail.com>
wrote:
> Scot you need to learm Python.
Do you mean learn *more* Python? Great, I'm always game to learn more!
I've taken a Python class and read books and run several Django sites.
It's not like I don't know enough Python to be functional. But we're
all here to learn. Just saying, there's no need to be snarky.
>The problem is you are defining get_class as
> an instance method and trying to call it is a class method (or static
> method).
Sorry, I have no idea what you're referring to here, and Googling for
static vs. class methods is not turning up anything I can understand.
Can you show what you mean by example? (i.e. how it pertains to this
problem)?
Thanks.
<snip>
The problem is you are defining get_class asan instance method and trying to call it is a class method (or staticmethod).
Sorry, I have no idea what you're referring to here, and Googling for
static vs. class methods is not turning up anything I can understand.
Can you show what you mean by example? (i.e. how it pertains to this
problem)?
Thanks.
>
> http://docs.python.org/library/functions.html#staticmethod
>
> It means that the method is function that, when you run it, doesn't specifically belong to any particular instance, but to the class itself.
>
> Shawn
Thanks Shawn. That URL's not working but I think I understand the
gist. To attach it to this problem: Usually when I define a method on
my model classes, they're accessible from views just attributes,
almost as if they were fields. In this case though I'm accessing the
model field or method not from a view but from admin.py and it's not
working. It sounds like you're saying that the model method is not
attaching to an instance like it usually does (which is why "self"
doesn't work). But I'm no closer to figuring out how why it's
different from model methods accessed from within views, or how I can
fix it.
Thanks.
It's different because the Media class is a class itself, even though
its definition is nested within the model/form class. It only has
access to the methods/properties/variables it contains (unless it is
given something else when constructed).
The solution to your problem is here -
http://docs.djangoproject.com/en/dev/topics/forms/media/#media-as-a-dynamic-property
Admin media is based on Forms media, so the same principles apply.
Sidenote - what's you've implemented is documented at the top of that
link, and as stated, it is designed for static media. follow the
'media as a dynamic property' section and you should be able to
achieve what you want.
Here's an example from my CkWidget class (no if blocks at the moment,
but you can easily add them there as it is just a normal instance
method inside your class):
def _media(self):
# add CKEditor JS to page. It is assumed that it is located at
# MEDIA_URL + 'js/ckeditor/ckeditor.js' unless base path is overridden
# in settings
js = [settings.CKEDITOR_BASEPATH + 'ckeditor.js']
return widgets.Media(js=js)
media = property(_media)
On Mar 25, 1:22 am, Sam Lai <samuel....@gmail.com> wrote:
> On 25 March 2010 09:25, Scot Hacker <shac...@berkeley.edu> wrote:
>
>
>
> > <snip>
> > It sounds like you're saying that the model method is not
> > attaching to an instance like it usually does (which is why "self"
> > doesn't work). But I'm no closer to figuring out how why it's
> > different from model methods accessed from within views, or how I can
> > fix it.
>
> It's different because the Media class is a class itself, even though
> its definition is nested within the model/form class. It only has
> access to the methods/properties/variables it contains (unless it is
> given something else when constructed).
Ah! Now I understand this distinction, thanks for that.
> The solution to your problem is here -http://docs.djangoproject.com/en/dev/topics/forms/media/#media-as-a-d...
>
> Admin media is based on Forms media, so the same principles apply.
>
> Sidenote - what's you've implemented is documented at the top of that
> link, and as stated, it is designed for static media. follow the
> 'media as a dynamic property' section and you should be able to
> achieve what you want.
That gets me part of the way there, but not quite.
>
> Here's an example from my CkWidget class (no if blocks at the moment,
> but you can easily add them there as it is just a normal instance
> method inside your class):
>
> def _media(self):
> # add CKEditor JS to page. It is assumed that it is located at
> # MEDIA_URL + 'js/ckeditor/ckeditor.js' unless base path is overridden
> # in settings
> js = [settings.CKEDITOR_BASEPATH + 'ckeditor.js']
>
> return widgets.Media(js=js)
>
> media = property(_media)
OK I've got something similar now, using _media rather than "class
Media:" Now all that remains is to do a conditional on the js= line.
That would be easy IF I could access fields on the model it references
to see what the boolean is currently set to. I've been reading
everything I can find, including
http://docs.djangoproject.com/en/dev/topics/forms/media/#media-as-a-dynamic-property
but still can't see how to access a field value on a model from the
admin.
To boil it down, is it possible to get something similar to the print
statement below to work (once I can print it out I can use it in the
conditional).
# models.py
class Tutorial(models.Model):
use_visual_editor = models.BooleanField()
# admin.py
class TutorialAdmin(admin.ModelAdmin):
def _media(self):
print [current value of use_visual_editor for the
instance]
js = ['/paths/to/media',]
return forms.Media(js=js)
media = property(_media)
admin.site.register(Tutorial, TutorialAdmin)
I appreciate your help - this has turned out to be one of those
problems that looks trivial but turns out hair-pulling. Thanks.
Ah right. You want the JS to apply to the form, not to the admin class
(JS in the admin class is loaded even when you're just looking at the
data in list view; while JS in the form is only loaded when you're
editing).
So you need to define a form for your model using forms.ModelForm.
class TutorialAdminForm(forms.ModelForm):
class Meta:
model = Tutorial
That should suffice; the ins and outs of model forms are here -
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/
Now instead of applying the above media code to the admin class, apply
it to your form class. Once in the form class, you have access to the
form's model instance via self.instance, e.g.
def _media(self):
print self.instance.use_visual_editor
js = ['/paths/to/media',]
return forms.Media(js=js)
media = property(_media)
Once that's done, you need to tell Django admin to use your new form
class, so change your admin class to the following:
class TutorialAdmin(admin.ModelAdmin):
form = TutorialAdminForm
And that should work. You need to make sure you have the right imports
for the various classes. I tend to define my forms in a separate
forms.py but that's up to you.
Hope that works.
>
> And that should work. You need to make sure you have the right imports
> for the various classes. I tend to define my forms in a separate
> forms.py but that's up to you.
Sam, you're a genius - that worked perfectly. Thanks SO much. I really
appreciate it.
Scot