Reputation: 4138
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.get(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?
Upvotes: 1
Views: 2487
Reputation: 16361
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.
Upvotes: 1