views:

1037

answers:

1

I would like to have a ConfirmationField field type. I want this field to work like a boolean field. I don't need to store this information on database instead I would like to store the date of confirmation on a seperate field.

class MyModel(models.Model):
    confirmation = ConfirmationField()


m = MyModel()
m.confirmation # False
m.confirmation_timestamp # None

m.confirmation = True
m.save()

m.confirmation_timestamp # datetime object


m.confirmation = False
m.save()

m.confirmation_timestamp # None again

I need to have both fields as Field instances, I need to be able to use them in Admin for example.

I have read the docs and checked the code, ForeignKey changes its database column name with the following code:

def get_attname(self):
    return '%s_id' % self.name

But I couldn't figure out exacly how I can use the rest of the code as an example. It seems my goal doesn't require tto much complexity.

I have also found ImageField saved extra information when the model is saved:

    if self.field.width_field:
        setattr(self.instance, self.field.width_field, self.width)
    if self.field.height_field:
        setattr(self.instance, self.field.height_field, self.height)

But of course I don't want confirmation itself to be stored in the database. I would cause redundancy since (confirmation_timestamp -> confirmation) None==False and <datetime instance>==True.

Any pointers/ideas are appreciated.

Thanks.

edit: It appears this is not currently possible. I have ended up changing my API. Here is a snipplet to give an idea how I did it:

    value = {'BooleanField': True,
             'DateTimeField': datetime.datetime.now(),
             'DateField': datetime.date.today(),
             'IntegerField': 1,
            }[instance._meta.get_field(field_name).get_internal_type()]
    setattr(instance, field_name, value)

You can have a confirmation field any type mentioned above and it sets the correct value. And confirmation checking can be done with bool(getattr(instance, field_name).

+4  A: 

Hi, if I got this right, consider:

class Modelname(models.Model):
    """(Modelname description)"""

    confirmation_timestamp = models.DateTimeField(blank=True)

    def _set_confirmation(self, value):
        if not value:
            self.confirmation_timestamp = None
        else:
            self.confirmation_timestamp = datetime.datetime.now()

    def _get_confirmation(self):
        return bool(self.confirmation_timestamp)

    confirmation = property(_get_confirmation, _set_confirmation)
    confirmation.short_description = "Confirmation"
    confirmation.boolean = True # have it nicely displayed in admin
ohnoes
Doesn't work; please fix the indentation.
Aaron Digulla
> confirmation.short_description = "Confirmation"> confirmation.boolean = True # have it nicely displayed in adminThese two lines don't seem to be right. Guess they're not confirmation attributes.
Rodrigo
Rodrigo, did you remember to put it in the list_display tuple @ admin.py?
ohnoes
Oh no, I just thought these were property attributes. So, they're not?
Rodrigo
mtod: Have you tried to run this? You can't add attributes to objects returned by property().
Aaron Digulla
ohnoes
ohnoes: you can try a descriptor instead and see if you can add attributes on it. But it's not what I'm looking for anyways; I want to add a field (and a corresponding database column) which creates another one under the hood.
muhuk