Ah, yes, I fell back on the add() function only because setattr wasn't
doing what I needed it to do.  I know I am getting the DoesNotExist
exception because the related model doesn't exist, but that's the
problem entirely: I have no way to pass an argument to setattr because
getattr raises this exception, and it's not going to exist until I
call

mymodel.some_relation_or_fk = related_model

This is the problem, because I don't know the name of the attribute
being used to define some_relation_or_fk.  However, since the
attribute that defines the relation seems to be a property, any
reference to it acts like a call to a get_function itself, which
raises the error.  So, given two model instances as per my previous
post:

something like:
>>> from project.models import MyModel
>>> my_model = MyModel(attr1 = 'value')
>>> my_model.attr1   # works fine, of course
'value'
>>> getattr(my_model, 'attr1') # also works, no surprises yet
'value'
>>> getattr(my_model, 'some_relation_or_fk') # but...
Traceback (most recent call last):
...
DoesNotExist

#Now, I realize that I was wrong in trying to call .add() on this side
of the relationship, but that is irrelevant to the problem (I had
actually made that attempt since I couldn't setattr).  This isn't
helpful of course, because in order to call setattr, I need to be able
to refer to the variable I want to set, and we just proved that
getattr is going to raise an exception, so I can't dynamically
establish this link.

However, by using the contenttypes package, I was able to side-step
this.  Since you asked for context, what I am trying to do is unify
separate models, here's an example using the auth system:

from django.db import models
from django.contrib.auth.models import User as Account
from project.decorators import link_model_to
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class User(models.Model):
    account_polymorphic_link = models.ForeignKey(ContentType)
    account_id = models.PositiveIntegerField()
    account = generic.GernericForeignKey('account_polymorphic_link',
'account_id')

    company = models.ForeignKey(Company)
    url = models.URLField(blank = True)
    address = models.CharField(max_length = 200)
    #...
    #more attributes, but important things like first_name, last_name,
username, password, etc. are in the Account relation (which prior to
using contenttypes could not be set dynamically

#The goal here is to be able to refer to the
django.contrib.models.User table as though its attributes were in the
current User table.
#To that end, I strapped together a decorator that works like this:

    @link_model_to(Account, through = 'account')
    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args,**kwargs)

I've actually gotten this working where I can enter the interpreter
and just do this:

from project.users.models import User

>>> me = User(first_name = "Alex", last_name = "G", username = "alexg", #stuff 
>>> in django user model that doesn't exist in mine
                state = "NJ", city = "...", ...) #stuff in my
project's User model in the same call
<User: alexg>
>>> me.account
<User: alexg> #this is the django user model
>>> me.first_name
"Alex"   #there is automatic passthrough to the subordinate model
>>> me.first_name = "Billy-Bob"
>>> me.account.first_name
"Billy-Bob"  #setting works too

So the decorator does the following:
1) initializes a new subordinate model instance in the event that (a)
one is not provided explicitly and (b) arguments exist for the
construction of said model and _associates it with the primary
model_*.
2) creates getters and setters that will allow you to refer to
subordinate model attributes through the primary model provided that
they are not shadowed (if an attribute with the same name exists in
the primary model, the argument does not pass to the subordinate one).

*is what I was having trouble doing due to getattr raising an
exception

I guess the real question here is, am I being really dense and is
there already a way to do this in django without resorting to this
decorator?

On Oct 8, 7:07 am, "Russell Keith-Magee" <[EMAIL PROTECTED]>
wrote:
> On Tue, Oct 7, 2008 at 9:59 PM, Alex G <[EMAIL PROTECTED]> wrote:
>
> > Ah, it works for me too, except in the case of relations.
>
> > Essentially, it all comes down to one line of code; given an instance
> > model, a method as a string, and a secondary instance of a model,
> > something like:
>
> > getattr(model_instance, attr_name).add(model_to_add)
>
> > So, something like:
>
> >>>> from project.models import MyModel
> >>>> my_model = MyModel(attr1 = 'value')
> >>>> my_model.attr1   # works fine, of course
> > 'value'
> >>>> getattr(my_model, 'attr1') # also works, no surprises yet
> > 'value'
> >>>> getattr(my_model, 'some_relation_or_fk') # but...
> > Traceback (most recent call last):
> >  File "<console>", line 1, in <module>
> >  File "/Library/Python/2.5/site-packages/django/db/models/fields/
> > related.py", line 235, in __get__
> >    raise self.field.rel.to.DoesNotExist
> > DoesNotExist
>
> > So I can't assign it to a variable (in order to set it)...  Any ideas?
>
> Your example isn't completely symmetric - I'm willing to be that if you tried:
>
> >>> mymodel.some_relation_or_fk
>
> you will get the same traceback.
> Traceback (most recent call last):
> ...
> DoesNotExist
>
> Look carefully at what the error says - it's telling you that the
> object that you have tried to retrieve doesn't exist - that is, the
> object that is currently referred to by 'some_relation_or_fk' doesn't
> exist.
>
> If you look in the underlying table, you will probably find that the
> some_relation_or_fk_id column contains a value (say, 3), but the
> related model doesn't have a instance with id=3. This can only happen
> if you're using a database without row-referential integrity (SQLite
> or MySQL with MyISAM).
>
> Also, just because you're getting errors with getattr doesn't mean you
> can't use setattr. In fact, in this case, the opposite is true - you
> need to set the field to get rid of the data integrity problem.
>
> You also need to be clear about which end of the relation we are
> dealing with. The error you are raising suggests that
> 'some_relation_or_fk' is the 'One' end of a OneToMany relation (i.e.,
> a foreign key) - yet your original code snippet talks about calling
> add(). If this is the case, you're dealing with the wrong end of the
> snake :-)
>
> As I said previously - we're going to need code to diagnose the
> problem. Specifically, the model that is causing problems. Talking in
> the abstract about 'some_relation_or_fk' is only going to give us both
> headaches :-)
>
> Yours,
> Russ Magee %-)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to