Dave E wrote:
> I have some data (page number references) that looks like this:
> 
> 320, 387..90, 410, 500
> 
> or (sustituting numerical .. ranges for conventional dashes)
> 
> 320, 387-90, 410, 500, 634
> 
> I'd just like to know the most Django-esque way of creating a model
> for these?
> 
> The requirements are:
> 
> 1. they're all numbers, or ranges of numbers
> 
> 2. there will be at least one - and an unknown number of other - page
> numbers or ranges, but not more than (say) 30.
> 
> I've looked through a lot of documentation (and custom fields), but
> can't find a tidy solution. I know that SET is a MySQL enxtension, so
> not handled by Django.
> 
> The issue has to be related to that of creating a model for HTML meta
> tags, except that these are all numbers or number ranges.

There are some other details you omit:

- how would you like to handle (or not-handle) overlapping 
ranges?  ("100..150, 120, 145-155")

- are ranges always specified the same way? (".." vs. "-")

- do you need to be able to sort the contents by page number? 
(and how does that interplay with overlapping ranges if allowed?)

- do you need to be able to find whether a given page is within 
the range of listed pages?

- are page numbers always integers?  (think Roman numerals used 
in pre-text matter, or appendices with page numbers like "B-13")

A couple thoughts occur to me:

1) just use a regexp-field and store them as a text-field (since 
you have a predefined cap of 30 you can get a rough estimate of a 
max...3 chars + 2 range characters + 3 chars + 1 comma + 1 space 
= 10 chars per range, * 30 references = 300 chars).  This allows 
for a small bit of validation, but doesn't offer much flexibility 
in terms of sorting/searching/overlaps.  It does allow for the 
Roman/appendix numbering scheme, depending on how tight you make 
your regexp

2) create a model like

    class PageRange(Model):
      source = ForeignKey(SomeOtherModel)
      start = PositiveIntegerField()
      end = PositiveIntegerField()
      def __repr__(self):
        if self.end:
          if self.end > self.start:
            return "%s-%s" % (self.start, self.end)
          elif self.end < self.start:
            return "INVERTED RANGE [%s-%s]" % (
              self.start, self.end)
        return str(self.start)

then perhaps do some population/checks on the save (start must be 
<= end; if end is Null, default to start; perhaps check for 
pre-existing ranges and see if these bounds fall within another 
one).  This has advantages that you can sort them, perform better 
checks on them, querying against them is easier, you can 
aggregate them to find the count, and you're not limited to an 
arbitrary number like 30.  Granted, many of these bits may not 
matter to you, but if you need the flexibility of any of them, 
the others come for free.

Just a few pre-breakfast rambling thoughts...

-tim







--~--~---------~--~----~------------~-------~--~----~
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