开发者

Django filter model using only unicode of an object

I have a model 'Objective', where the usual way to refer to objects is by the unicode method.

models.py:

class Objective(models.Model):
    level = models.IntegerField()
    strand = models.ForeignKey(Strand)
    order = models.IntegerField()
    description = models.TextField()
    def __unicode__(self):
        return u'%s%s%s' % (self.level, self.strand.code, self.order)

    class Meta:
        unique_together = ("strand", "level", "order")
        ordering = ['level', 'strand', 'order']

An example object in this model would be called e.g. 6ssm4, for the fourth entry in the ssm strand at level 6. I want to do my lookups (say from url parsing) by referring to this unicode string.

urls.py:

(r'^(?P<objective>[^/]+)/$', 'display_objective'),

I have tried all of the following variations as lines in views.py (not all at once!):

def display_objective(request, objective):
    theobjective = Objective.objects.get(unicode() = objective)
    theobjective = Objective.objects.get(self.unicode = objective)
    theobjective = Objective.objects.get(__unicode__ = objective)
    theobjective = Objective.objects.get(objective__iexact = objective)
    theobjective = Objective.objects.g开发者_开发知识库et(objective)
    theobjective = Objective.objects.get(unicode() = objective)

But if I go to http://localhost:8000/6ssm4/ I get the error page with errors like "Keyword can't be an expression" or "Cannot resolve keyword 'self' into field. Choices are: assessment, description, id, level, order, strand".

Is this a legitimate way to lookup objects, or should I be dissecting the keyword? If it is legit, what is the correct syntax?


The ORM converts filter lvalues (the things on the left side of the equals sign) into SQL lookup terms, which is why it has a limited syntax. You can't make a Python function a SQL lookup term; the database knows nothing about Python.

One correct way to do this would be to create a new field in your table, call it index or lookup, and then do this:

def save(self, *args, **kwargs):
    self.lookup = self.__unicode__()
    super(Objective, self).save(*args, **kwargs)

The lookup field becomes a pre-processed member of your table; every time you save an Objective, a lookup-ready version of it gets stored in the table. You can then:

theobjective = Objective.objects.get(lookup = objective)

Your alternative is to break the objective into its component parts and filter on level, strand, and order, but that only works if they're sufficiently regular for a regular expression.

This is a classic tradeoff of programmer time vs. responsiveness vs. storage (pick two). In this case, I've made the call that programmer time and responsiveness are more important that storage considerations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜