views:

40

answers:

2

I have a database table with e.g. a weight value e.g.

CREATE TABLE product (
    id SERIAL  NOT NULL,
    product_name item_name  NOT NULL,
    .
    .

    weight NUMERIC(7,3), -- the weight in kg
    .
    .
    CONSTRAINT PK_product PRIMARY KEY (id)
);

This results is the model:

class Product(models.Model):
    .
    weight = models.DecimalField(max_digits=7, decimal_places=3, blank=True, null=True)
    .

I store the weight in kg's, i.e. 1 kg is stores as 1, 0.1 kg or 100g is stored as 0.1

To make it easier for the user, I display the weight in the Admin list display in grams by specifying:

def show_weight(self):
    if self.weight:
        weight_in_g = self.weight * 1000
        return '%0f' % weight_in_g

So if a product weighs e.g. 0.5 kg and is stored in the database as such, the admin list display shows 500

Is there also a way to alter the number shown in the 'Change product' window. This window now shows the value extracted from the database, i.e. 0.5. This will confuse a user when I tell him with the help_text to enter the number in g, while seeing the number of kgs.

Before saving the product I override save as follows:

def save(self):
    if self.weight:
        self.weight = self.weight / 1000

This converts the number entered in grams to kgs.

A: 

Why not just use an Integer, and only store the weight grams?

dysmsyd
Well the case shown is just an example. I just want to know if you can change (scale) the displayed values in the 'Change object' window.
Henri
+1  A: 

Model's save method like this can produce unexpected results and probably not what you want anyway. You see, every time you save a model it's weight will become 1000 times smaller.

It would be better to add custom ModelForm and to override ModelAdmin.save_model. And here we go, little example for the inspiration (not tested in any way):

class ProductForm(forms.ModelForm):
    weight_gramms = forms.IntegerField(...)

    class Meta:
        model = ProductModel
        exclude = ('weight',)

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        if self.instance:
            self.initial['weight_gramms'] = int(self.instance.weight * 1000)

class ProductAdmin(admin.ModelAdmin):
    form = ProductForm

    def save_model(self, request, obj, form, change):
        obj.weight = form.cleaned_data['weight_gramms'] / 1000.0
        obj.save()
alex vasi