# Best Practices for updating one field based on another

**URL:** <https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390>\
**Category:** Getting Started\
**Created:** [April 20, 2023, 8:55am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390 "2023-04-20T08:55:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 20, 2023, 8:55am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/1 "2023-04-20T08:55:12Z")

</div>

Hello I am new to django and wondering what the best practices are for a model I am designing.

I have a field, tn, which needs to increase by one every time a new instance of that class is created. I also have another field, Counter, which needs to increase by 1 every n times tn increases. What is the best practice here? Is it better to have Counter as a separate class or a field within tn?

Depending on which is better how would you go about doing that? Any help is greatly appreciated.

> ```auto
> class Tn(models.model):
> tn = models.PositiveIntegerField(unique=True, primary_key=True, editable=False)
> counter = models.PositiveIntegerField(editable=False
> 
> ```

)

---

<div class="post-metadata">

**Author:** ![leandrodesouzadev](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/leandrodesouzadev/32/8981_2.png) [@leandrodesouzadev](https://forum.djangoproject.com/u/leandrodesouzadev)\
**Post date:** [April 20, 2023, 10:30am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/2 "2023-04-20T10:30:54Z")

</div>

I’m a bit confused.  
What are you trying to accomplish?

But if i understood correctly  
The `tn` field should be a `AutoField` or `BigAutoField`, this [documentation](https://docs.djangoproject.com/en/4.2/ref/models/fields/#autofield) covers them.  
But the `counter` field is always to be the same as the maximum number of `tn`, if that’s the case, then this should not be a field on the database, but a computed valued. See [aggregation](https://docs.djangoproject.com/en/4.2/topics/db/aggregation/#aggregation) and the section [Cheat Sheet](https://docs.djangoproject.com/en/4.2/topics/db/aggregation/#cheat-sheet) contains a example using the `Max` function

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 20, 2023, 11:46am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/3 "2023-04-20T11:46:24Z")

</div>

Hello thank you for your quick reply, I think I understand about the TN field - I have read that and changed it to:

> tn = models.AutoField(primary\_key=True)

I want the Counter field to increase every time TN is divisible by 40 without remainder or every 40 tn.  
So for example:  
TN 1-40, Counter 1  
TN 41-80, Counter 2  
TN 81-120, Counter 3  
etc.  
Does this make more sense what I am trying to achieve?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 20, 2023, 11:59am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/4 "2023-04-20T11:59:33Z")

</div>

Since this can be computed quickly from tn, I would not make it a separate field. I would compute it on the fly as necessary.

Side note: In a production environment, you _may_ end up with “gaps” in your sequence. There is no guarantee that you will have an instance of your model for every distinct value of tn. You need to decide how important that factor is, and how that affects your Counter.

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 20, 2023, 12:04pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/5 "2023-04-20T12:04:40Z")

</div>

Hi Ken, thanks for your reply.

How would I end up with gaps? with tn defined as this:

> tn = models.AutoField(primary\_key=True)

Will the tn not just automatically increase.  
How would I compute it on the fly? I have this in my models.py file not sure if this is the right way to go:

> counter\_number = models.PositiveIntegerField(editable=False)
> 
> ```
> @property
> def _counter_number(self, request): 
> if type(self.tn/40) == int:
> self.counter_number += 1
> return self.counter_number
>    
> def save(self, *args, **kwargs):
> self.counter_number = self._counter_number
> super().save(*args, **kwargs)
> 
> ```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 20, 2023, 12:17pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/6 "2023-04-20T12:17:22Z")

</div>

> [@gbwlucite](#):
>
> How would I end up with gaps?

Because in a production environment, you will have multiple processes running. Process A may get value 345 to assign while process B gets 346. Now, if process A fails for _whatever_ reason, you will not have a 345 in the database. Process C is _not_ going to go back to fill the gap, it’s going to continue on with 347.

How likely this is to happen will depend upon the system load and the reliability of the systems being run (host, database, network between them, network between the server and the user, etc, etc, etc.)

Side note: I’d use `if self.tn % 40 == 0: return self.tn//40`.

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 20, 2023, 12:24pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/7 "2023-04-20T12:24:01Z")

</div>

Hi Ken,

I see - that’s fine, counter doesn’t need to be for EXACTLY 40 a few errors will be ok, also thinking about the number of users at once etc I don’t think it will be a problem. What will happen if an entry of TN gets deleted? Will the Counter value persist?

> @property  
> def \_counter\_number(self):  
> if self.tn % 40 == 0:  
> return self.tn//40

```
def save(self, *args, **kwargs):
    self.net_weight = self._net_weight_calculator
    self.counter_number = self._counter_number
    super().save(*args, **kwargs)

```

Few questions:

- Is it correct to definre this as a method of the class in the models.py file?
- what is the purpose of the \*args \*\*kwargs and are they neccessary?  
Thanks again

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 8:04am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/8 "2023-04-21T08:04:43Z")

</div>

Hi Ken, I have tried this above and in my admin.py file I get the following error:

> Exception Type: FieldError at /admin/stocks/weighbridge/add/  
> Exception Value: Unknown field(s) (counter\_number) specified for Weighbridge. Check fields/fieldsets/exclude attributes of class WeighbridgeAdmin.

I also get a similar error for self.net\_weight. How do I use the results of the \_counter\_number property? as a field?

Any help is greatly appreciated.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 11:37am UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/9 "2023-04-21T11:37:38Z")

</div>

I would need to see what you currently have as the complete class, along with your ModelAdmin class to see how it’s being used.

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 12:23pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/10 "2023-04-21T12:23:48Z")

</div>

Hi Ken,

This is what I’ve got but not sure it is best practices, and it works with the lines commented out but when I try to use them I get a different type of error.

```auto
#models.py
class InloadBook(models.Model):
    tn = models.OneToOneField(Weighbridge, primary_key=True, on_delete=models.PROTECT)
    
    counter_number = models.IntegerField(verbose_name='Counter Number', default=0)
    
    def save(self, *args, **kwargs):
        #if self.tn % 40 == 0: 
        # self.counter_number = self.tn//40
        #else:
        
        self.counter_number = 1 
        super(InloadBook, self).save(*args, **kwargs)

```

```auto
#admin.py
from .models import InloadBook
admin.site.register(InloadBook)

```

With those lines uncommeted I get this error:

```auto
 File "C:\Users\georg\onedrive\storeapp\demo0922\stocks\models.py", line 173, in save
    if self.tn % 40 == 0:
       ^^^^^^^^^^^^

Exception Type: TypeError at /admin/stocks/inloadbook/add/
Exception Value: unsupported operand type(s) for %: 'Weighbridge' and 'int'

```

I get I probably need some sort of clause for the data types but not sure the best way to go about this rather than fudging something that isn’t ideal I’d like to learn how to do it the best way.

Does this make sense?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 12:46pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/11 "2023-04-21T12:46:23Z")

</div>

> [@gbwlucite](#):
>
> `if self.tn % 40 == 0:`

Correct, because `tn` is not a value in `Inloadbook`. Here, `tn` is an instance of `Weightbridge`. (In your earlier example, `tn` was a value, an `AutoField` - I don’t understand what you’re trying to do here.)  
What does your `Weightbridge` model look like?

It may even be better if you just tried to explain a little bit of the background and what you’re trying to model with this.

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 12:52pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/12 "2023-04-21T12:52:25Z")

</div>

Hey Ken, yes I have moved my Counter field to another class as it makes more sense with the data. The overall picture is I am trying to develop a Weighbridge system that has tickets for when a delivery is made and every 40 loads that are a delivery not a collection (i.e. Inload) need to be grouped together using the Counter field. so the tn is the primary key on the weighbridge class and also the primary key on the inload in a onetoone relationship. the weighbridge class looks like this:

```auto
#models.py
class Weighbridge(models.Model):
    weighdate = models.DateTimeField(default=now)
    tn = models.AutoField(primary_key=True) 

    PAYMENT_CHOICE = [( "PO",'£'), ('CA', "CASH"), ("AC",'ACC'), ('CH', 'CHEQUE')]
    payment = models.CharField(choices=PAYMENT_CHOICE, max_length=20, default='AC')
    quality_control = models.BooleanField(default=True, verbose_name='The Vehicle/Trailer has been inspected and is clean & ready for Loading/Tipping') #REMOVE THE DEFAULT

    supplier = models.ForeignKey(Supplier,on_delete=models.PROTECT)
    variety = models.ManyToManyField(to=Variety, related_name='weighbridge', blank=True) 
    loading_statement = models.BooleanField(default=True, verbose_name='Loading / Unloading Equipment Clean and Ready for Use.' )

#etc...

```

and inload book as above.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 12:55pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/13 "2023-04-21T12:55:17Z")

</div>

So if `x` is an instance of `Weightbridge`, how would you access _any_ attribute of `x`? (For example, how would you access the `weighdate` attribute of `x`?)

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 1:00pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/14 "2023-04-21T13:00:24Z")

</div>

in the admin.py file? this is the code I have for that:

```auto

class ReferencesInline(admin.TabularInline):
    model = Reference
    extra = 3

class LastLoadInline(admin.TabularInline):
    model = LastLoad
    extra = 3
    max_num = 3

class WeighbridgeAdmin(admin.ModelAdmin):
    
    
    readonly_fields = ['tn', 'weighdate', 'net_weight']
    inlines = [ReferencesInline, LastLoadInline]
    fieldsets = [
        ('Load Details', {'fields':[('tn','weighdate', 'payment','supplier'), 'quality_control', 'loading_statement' ,'variety']}),
        ('Delivery/Collection Details', {'fields':['store_location', 'external_location', ('weight_one', 'weight_two', 'net_weight')], 'classes':('wide', 'extrapretty')},), # 
        ('TASCC CODE OF PRACTICE CONDITIONS APPLY', {'fields':[]}),
        ('Haulage', {'fields':[('tr_no', 'registration','comments'), ('weighoperator_name', 'driver_name')]})
    ]
    
    list_display = ('weighdate', 'supplier', 'net_weight', 'store_location', 'external_location')
    
    #'net_weight')
    list_filter = ['tn','supplier', 'store_location', 'variety']
    search_fields = ['supplier', 'variety']
    date_hierarchy = 'weighdate' 

```

I cut some fields from the last cut and paste as its a bit long. But the idea is the same. Does this answer your question?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 1:03pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/15 "2023-04-21T13:03:40Z")

</div>

No it doesn’t - I’m asking a very specific and limited question.

If you have the query:  
`a_weigh_bridge = Weighbridge.objects.get(pk=10)`  
then `a_weigh_bridge` is an instance of `Weighbridge`.

What **one** line of code can you write that would print the value of the `weighdate` attribute of `a_weigh_bridge`?

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 1:05pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/16 "2023-04-21T13:05:58Z")

</div>

I am really not sure but would it be something like:  
`print(a_weigh_bridge.weighdate())`

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 1:12pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/17 "2023-04-21T13:12:50Z")

</div>

Close, but not a function. `a_weigh_bridge.weighdate`.

If you’re not comfortable with objects and object attribute access, you may wish to review [9. Classes — Python 3.11.3 documentation](https://docs.python.org/3/tutorial/classes.html) and the work that you did with [Writing your first Django app, part 1 | Django documentation | Django](https://docs.djangoproject.com/en/4.0/intro/tutorial01/)

Anyway, with this in mind, if `self.tn` is an instance of `Weighbridge`, how would you then access the `tn` attribute of that object? (Again, looking for one statement.)

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 1:20pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/18 "2023-04-21T13:20:01Z")

</div>

ok thank you - I have read both of these before (the second link multiple times) but theory and practice don’t always marry up properly (Sorry!).

`Weighbridge.objects.get(pk=self.tn).tn`

If this is correct - why do we need to do this and not just use `self.tn`?

Thank you Ken, sorry for my complete misunderstanding here…  
Georgia

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 21, 2023, 1:32pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/19 "2023-04-21T13:32:13Z")

</div>

Nope, let’s take another step back.

`self.tn` **is** the reference to the Weighbridge object. You do not need to execute another query.

`self.tn.tn` is then the reference to the `tn` attribute of that `Weighbridge` object.

---

<div class="post-metadata">

**Author:** ![gbwlucite](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/gbwlucite/32/13337_2.png) [@gbwlucite](https://forum.djangoproject.com/u/gbwlucite)\
**Post date:** [April 21, 2023, 1:34pm UTC](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390/20 "2023-04-21T13:34:44Z")

</div>

ok so if I wanted the supplier for that same tn would it be `self.tn.supplier ` ? and we can use `self.tn` to reference the specific Weighbridge object because it is the primary key?

[Next page](https://forum.djangoproject.com/t/best-practices-for-updating-one-field-based-on-another/20390.md?page=2)
