Reputation: 12860
I have a model in Django with a method that I can't seem to access in the view. Here is the model:
class Realtor(models.Model):
user = models.OneToOneField(User)
team = models.ForeignKey(RealtorTeam, blank=True, null=True, default=None)
is_showing_realtor = models.BooleanField(default=False)
is_listing_realtor = models.BooleanField(default=False)
def type(self):
if self.is_showing_realtor and self.is_listing_realtor:
return 'Showing and Listing'
elif self.is_showing_realtor:
return 'Showing'
elif self.is_listing_realtor:
return 'Listing'
else:
return ''
Now, in the view, I try to query the model, including the method, like this:
q = Realtor.objects.all()
q = q.filter(user__first_name__icontains=first)
q = q.filter(user__last_name__icontains=last)
q = q.filter(team__name__icontains=team)
q = q.filter(user__email__icontains=email)
q = q.filter(type__icontains=type)
The error I get is Cannot resolve keyword 'type' into field. Choices are...
. I looked up a number of stackoverflow questions, and read through more of the Django docs, and I saw to add a field like this in the model:
type_display = (type,)
But that didn't work. Do I have to query the is_showing_realtor and is_listing_realtor? Is there no way to query the method?
We are using Django_tables2 to display tables of models. We are able to access the type
method with that, like this:
class RealtorTable(tables.Table):
id = tables.Column()
first_name = tables.Column(accessor='user.first_name', order_by='user.first_name')
last_name = tables.Column(accessor='user.last_name', order_by='user.last_name')
team = tables.Column()
email = tables.Column(accessor='user.email', order_by='user.email')
type = tables.Column(order_by='is_showing_realtor')
But still, can't pass it to the view.
Upvotes: 1
Views: 187
Reputation: 10397
I'm no Django expert, but I'm pretty sure that you can't query on model attributes that aren't columns in the database, which is what you are trying to do. Perhaps try to decorate the method with @property
to make it like an attribute.
You could just do a list comprehension if like
results = [m for m in query_set if m.type = "Showing and listing"]
Upvotes: 1
Reputation: 20341
type
is the name of a built-in function python, and so also in django. I'd recommend renaming your function to something like listing_type
to avoid any clashes.
In particular, this line
type_display = (type,)
probably isn't doing what you think it is.
reptilicus is correct, I'd not spotted the filter on a non-field attribute, that doesn't make sense. You could turn listing_type
into a CharField
with choices=
set, and then some custom save()
logic to set it when the model is changed - or you could use property
@def listing_type():
doc = "The listing_type property."
def fget(self):
if self.is_showing_realtor and self.is_listing_realtor:
return 'Showing and Listing'
elif self.is_showing_realtor:
return 'Showing'
elif self.is_listing_realtor:
return 'Listing'
else:
return ''
def fset(self, value):
self._listing_type = value
def fdel(self):
del self._listing_type
return locals()
listing_type = property(**listing_type())
PS I still don't like type
:-)
Upvotes: 2