On Wed, Dec 31, 2008 at 6:02 AM, bruno desthuilliers <
bruno.desthuilli...@gmail.com> wrote:

>
>
>
> On 31 déc, 05:40, schwim <gsch...@gmail.com> wrote:
> > I'm trying to build a model that will store the counts of each of 10
> > possible choices, e.g.:
> >
> >     v1 = models.IntegerField(default=0)
> >     v2 = models.IntegerField(default=0)
> >     v3 = models.IntegerField(default=0)
> >     ...
> >     v10 = models.IntegerField(default=0)
> >
> > I'd prefer to represent this as an array
>
> Where ?
>
> > rather than 10 separate
> > fields.  I looked at the CommaSeparatedIntegerField as an alternative,
> > but I want to explicitly state that there are 10 entries available per
> > instance.
>
> Note that at the Python level, a list (I suppose that's what you mean
> by 'array') is not fixed-length.


Yes, that is what I meant actually. I'm new to python, a perl convert I
guess you could say.


>
>
> If all you want is a way to access the values as a sequence (read-
> only) from your python/templates code, it's just a matter of adding a
> simple property:
>
>
> class YourModel(models.Model):
>    # you code here
>    @property
>    def values(self):
>        return [getattr(self, "v%s" % i) for i in range(1,11)]
>
>
> then:
>
> m = YourModel.objects.get(...)
> m.values
> m.values[0]
> m.values[9]


Yes, I think this would work nicely actually.  I really only need to access
the values as a list when reading. Writes will be specific.




>
>
>
> If you want a reliable read-write property, this becomes a bit more
> involved. You have to write a custom descriptor returning a custom
> sequence type that retains a reference on the model instance.
>
> The following code should get you started - warning: it's Q&D, full of
> magic numbers, not generic, not factorized, and not even tested.
> IOW : it's by no mean production code.
>
> class MySequence(object):
>    def __init__(self, model):
>        self._model = model
>
>    def _as_fieldname(self, index):
>        # sequences are zero-based
>        # XXX : magic number
>        if not 0 <= index <= 9:
>            raise IndexError
>        # your fields are 1-based
>        # XXX duplicated in MySequenceDescriptor
>        return "v%s" % (index+1)
>
>    def __getitem__(self, index):
>        fname = self._as_fieldname(index)
>        return getattr(self._model, fname)
>
>    def __setitem__(self, index, value):
>        fname = self._as_fieldname(index)
>        setattr(self._model, fname, value)
>
>    # you may need some other sequence __magicmethods__ here
>    # check the Python's manual about emulating sequence types
>
>
> class MySequenceDescriptor(object):
>    def __get__(self, instance, cls):
>        if instance is None:
>            # looked up in the class
>            return self
>        # looked up on a model instance:
>        return MySequence(instance)
>
>    def __set__(self, instance, value):
>        # expects a sequence of len(10)
>        # XXX : magic number
>        if len(value) != 10:
>            raise ValueError("yadda yadda")
>        for index, val in enumerate(value):
>            # XXX duplication of  MySequence._as_fieldname
>            setattr(instance, "v%s" % (index+1), val)
>
>
> class YourModel(models.Model):
>    # your code here
>
>    values = MySequenceDescriptor()
>
> HTH
>
>
Very helpful, yes, thank you.  I think I understand your approach here, but
it's probably more complicated than I need.

--~--~---------~--~----~------------~-------~--~----~
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 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to