How to override an attribute?

48 views
Skip to first unread message

.

unread,
Aug 4, 2012, 2:55:13 PM8/4/12
to Django users
Hello,

I'm trying to do the same [1].
I've already tried all solutions from stackoverflow but none of them
worked.

[1] http://stackoverflow.com/questions/2344751/in-django-model-inheritance-does-it-allow-you-to-override-a-parent-models-a

Karen Tracey

unread,
Aug 4, 2012, 3:16:11 PM8/4/12
to django...@googlegroups.com

It seems you are trying to do something that is specifically documented as not being allowed:

https://docs.djangoproject.com/en/1.4/topics/db/models/#field-name-hiding-is-not-permitted

Easiest solution to your underlying problem would likely be to find a solution that does not require doing something Django does not support.

Karen
--
http://tracey.org/kmt/

.

unread,
Aug 4, 2012, 5:21:47 PM8/4/12
to django...@googlegroups.com
> https://docs.djangoproject.com/en/1.4/topics/db/models/#field-name-hiding-is-not-permitted

I've already seen this link on stackoverflow.

> Easiest solution to your underlying problem would likely be to find a solution that does not require doing something Django does not support.

Do you have an idea how to do the following without "doing something
Django does not support"?

1. Each class should have the same attribute: a unique name.
For example:
class Foo(): ...
class Bar(Foo): ...

Foo.name should return "Foo"
Bar.name should return "Bar"

2. name should be a field not just a string. (I want to store names in
the database.)


Cheers

lacry...@gmail.com

unread,
Aug 4, 2012, 8:28:22 PM8/4/12
to django...@googlegroups.com

It's hard to say without the real ino, and not kowing why you want the info to be a field, I see no good reason you´d want a db field where all instances of a given model would share the same value.

But assuming you just want to set up a default, and be able to override it at will, you can always do:
class Foo:
def default_name(self):
return 'Foo'
name = CharField(default=default_name)

Class Bar(Foo):
def default_name(self):
return "Bar"

If you want it ACTUALLY to be theclass name, you don't even need to redefine it, you can just return self__class__,__name__

If you don´t want to be able change it in a per instance basis, then you´ re going about this the wrong way
-----Mensaje original-----
De: .
Enviados: 04/08/2012 14:21:47
Asunto: Re: How to override an attribute?
--
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.


Melvyn Sopacua

unread,
Aug 4, 2012, 8:46:41 PM8/4/12
to django...@googlegroups.com
On 4-8-2012 19:21, . wrote:

> 1. Each class should have the same attribute: a unique name.
> For example:
> class Foo(): ...
> class Bar(Foo): ...

This makes very little sense if you use pseudo code. Why would a
database table need it's name stored in every record? That's what you're
saying above translated to the database layer.

Either provide actual code that makes sense or rethink if what you're
doing is really needed.

--
Melvyn Sopacua

.

unread,
Aug 5, 2012, 5:53:51 AM8/5/12
to django...@googlegroups.com
> But assuming you just want to set up a default, and  be able to override it at will, you can always do:
> class Foo:
>    def default_name(self):
>       return 'Foo'
>    name = CharField(default=default_name)

> Class Bar(Foo):
>    def default_name(self):
>      return "Bar"

This looks right but I can't check it.

There is a class (let's call it Foo) which is a subclass of User.
Foo has the following line in its Meta:
proxy = True

When I try to validate my models this error appears:
django.core.exceptions.FieldError: Proxy model 'Foo' contains model fields.

I will get another error if I remove "proxy = True":

Error: One or more models did not validate:
app.foo: Accessor for field 'user_ptr' clashes with related field
'User.foo'. Add a related_name argument to the definition for
'user_ptr'.

I've read a doc page on inheritance but I don't know how to fix these errors.


Thanks

Victor Rocha

unread,
Aug 5, 2012, 2:35:30 PM8/5/12
to django...@googlegroups.com
What about you do what the error is telling you to do?
All you need to do its to add a related name to your field definitions and that will fix it.

If you need me to fix it for you, post some real code.

Tomas Neme

unread,
Aug 5, 2012, 9:09:37 PM8/5/12
to django...@googlegroups.com
> There is a class (let's call it Foo) which is a subclass of User.
> Foo has the following line in its Meta:
> proxy = True

if you don't provide full minimal data, it's hard for us to help. If I
had known you were using a proxy model, I'd have proposed something
different.

In general, unless you got a good reason, I'd recommend against
subclassing User, use a profile instead. If you *really* need to
subclass or override it, first go read the docs about overriding the
User class, *and* all the documentation about models and model
inheritance.

Things should be pretty clear, whether you want a proxy model or not,
where in the inheritance tree it should be, and how to set it up.
THEN, if you have some issue with your class schema, you'll be able to
realize what you need, and be sure whether you really need to do what
django is complaining about, or if there's a better way of doing it.

For the time being, I suggest you drop all the Foos and Bars, post
some real code, and explain why do you feel the need to subclass the
User model

--
"The whole of Japan is pure invention. There is no such country, there
are no such people" --Oscar Wilde

|_|0|_|
|_|_|0|
|0|0|0|

(\__/)
(='.'=)This is Bunny. Copy and paste bunny
(")_(") to help him gain world domination.

Tomas Neme

unread,
Aug 5, 2012, 9:11:20 PM8/5/12
to django...@googlegroups.com
I don't mean to say you shouldn't need to ask questions, I just say
that using or not "proxy" is not a "let's see what happens" choice,
and having the docs read and halfway understood will help you ask *the
right* questions

Melvyn Sopacua

unread,
Aug 6, 2012, 12:32:59 AM8/6/12
to django...@googlegroups.com
Agreeing with Thomas. But for the archives some background on django
inheritance:

On 5-8-2012 7:53, . wrote:

> I've read a doc page on inheritance but I don't know how to fix these errors.

In python you can override any attribute or method.
In django being a python application obviously the same applies, however
django customizes class creation for models and tucks away the field
definitions in the meta class. It therefore does not allow you to
override model fields by raising exceptions at class creation.
Django has to do this, so you or a model form can assign a value to a
model attribute and django still knows what the field definition is so
it can validate and save it. So for a model instance of a 'Person' model:
bob.name = 'Bob Jones'
bob.save()
what happens:
for field in bob._meta.fields : # that's where the field defs end up
if field.name == 'name' :
field.value = 'Bob Jones'

You *can* however implement a model field on a model class that has a
property with the same name. For example:

class Person(models.Model) :
name = models.CharField(max_length=32)

@property
def is_pregnant(self) :
return False
@pregnant.setter
def is_pregnant(self, value) :
pass

class Man(Person) :
pass

class Woman(Person) :
is_pregnant = models.BooleanField()

--
Melvyn Sopacua

Nickolas Grigoriadis

unread,
Aug 6, 2012, 5:46:08 AM8/6/12
to django...@googlegroups.com
What I found useful sometimes, was to store the content_type_id of the object, so when I open the parent class, I can change the type to the right subclass.

For example:

from django.contrib.contenttypes.models import ContentType

class Parent(models.Model):
    content_type = models.ForeignKey(ContentType)

    def save(self, *args, **kwargs):
        self.content_type = ContentType.objects.get_for_model(self)
        super(Parent, self).save(*args, **kwargs) # Call the "real" save() method.

    def get_real(self):
        return self.content_type.model_class().objects.get(pk=self.pk)


Can that help?
Reply all
Reply to author
Forward
0 new messages