Philippos
Philippos

Reputation: 103

Django : Manipulate Data in a generic.ListView

I wonder if it's possible to apply a rule on every record of a ListView Example : get from a model a value in grams and create a new var containing the kg value if the gram value > 1000

I have tried with get_object but it only works for ViewDetail

Thanks in advance for your help :)

class ViewBsin(generic.ListView):
template_name = 'browser/bsin.html'
context_object_name = 'gtin_list'
model = Gtin
...
def get_object(self):
    # Call the superclass
    object = super(ViewBsin, self).get_object()
    # Add new data
    if object.M_G and object.M_G >= 1000:
        object.M_KG = object.M_G / 1000
    if object.M_ML and object.M_ML >= 1000:
        object.M_L = object.M_ML / 1000
    object.save()
    # Return the object
return object

Upvotes: 2

Views: 744

Answers (1)

Alasdair
Alasdair

Reputation: 308949

You could override get_queryset and loop through the querysets, updating the objects. You shouldn't call save() because this would update the database, and ListView should be read only.

class ViewBsin(generic.ListView):

    def get_queryset(self):
        queryset = super(ViewBsin, self).get_queryset()
        for obj in queryset:
            if obj.M_G and obj.M_G >= 1000:
                obj.M_KG = obj.M_G / 1000
            # Make any other changes to the obj here
            # Don't save the obj to the database -- ListView should be read only
        return queryset

A different approach would be to write a custom filter that converts grams to kilograms.

Then, in your template, instead of writing

{{ object.M_KG }}

You would do

{{ object.M_G|to_kg }}

If you have more custom logic, like 'display KG if g > 1000, otherwise display g', then this can all go in the template filter as well. This simplifies your templates, and keeps display logic out of the view.

Upvotes: 2

Related Questions