Django: returning a selection of fields from a model based on their values?
I am working with some data over which I have little control. I'd like to return ONLY the fields of my model that aren't certain 'uninteresting' values (e.g. '0', 'X' or '-'), and access them individually in the template.
My model is like this:
class Manors(models.Model):
structidx = models.IntegerField(primary_key=True, verbose_name="ID")
hills = models.CharField(max_length=100, null=True, blank=True, verbose_name="Number of fields")
In my template, I return a QuerySet of Manors, and I'd like to output something like this if the hills field isn't uninteresting:
{% for manor in manors %}
{% if manor.hills %}<li>Hills blah blah: {{ manor.hills }}</li>{% endif %}
{% endfor %}
I want to avoid too much logic in the template. Ideally, the manor object would simply not return with the uninteresting fields attached, then I could just do {% if manor.hills %}
.
----UPDATE---- I could use a dictionary, like below, but it feels very inefficient - it would be better to return a QuerySet with just the interesting fields attached. Is that possible? -----------
I tried writing a model method that returns a dictionary of the interesting values, like this:
def get_field_dictionary(self):
interesting_fields = {}
for field 开发者_高级运维in Manors._meta.fields:
if field.value_to_string(self) != "N" and field.value_to_string(self) != "0" and field.value_to_string(self) != "-" and field.value_to_string(self) != "X":
interesting_fields[field.name] = field.value_to_string(self)
return interesting_fields
But I don't know how to access individual values of the dictionary in the template:
{% if manor.get_field_dictionary['hills'] %}<li>Hills blah blah: {{ manor.get_field_dictionary['hills'] }}</li>{% endif %}
gives a TemplateSyntaxError. Is there a better way to do this?
UPDATE: this did it in the end, as a method on the model.
def get_interesting_queryset(self):
for field in Manors._meta.fields:
if field.value_to_string(self) is None or field.value_to_string(self) == "N" or field.value_to_string(self) == "0" or field.value_to_string(self) == "-" or field.value_to_string(self) == "X" or field.value_to_string(self) == "":
delattr(self, str(field.name))
return self
Depending on the version of Django you are using, you should use the "in" operator. Lets take your model function. Have it output a list.
def get_field_list(self):
interesting_fields = []
for field in Manors._meta.fields:
if field.value_to_string(self) != "N" and field.value_to_string(self) != "0" and field.value_to_string(self) != "-" and field.value_to_string(self) != "X":
interesting_fields[] = field.value_to_string(self)
return interesting_fields
Then. In your template do the following.
{% if 'hills' in manor.get_field_list %}<li>Hills blah blah: {{ manor.hills }}</li>{% endif %}
Also note that once you have the queryset, IIRC, you can edit it. Thus
for manor in Manors.objects.all():
for field in Manors._meta.fields:
if field.value_to_string(manor) == "N" or field.value_to_string(manor) == "0" or field.value_to_string(manor) == "-" or field.value_to_string(manor) == "X":
delattr(manor, field.value_to_string(self))
Try this...
{% for k,v in manor.get_field_dictionary %}
{% ifequal k "hills" %}
<li>Hills blah blah: {{v}}</li>
{% endifequal %}
{% endfor %}
Assuming the model method works, that should get you what you're looking for.
精彩评论