0

Model field displaying some zip codes as 4 characters only, ex: 1234

I want to change all zip codes with 4 characters to 5 by adding a "0" at the start, ex: 01234

Trying to find a way to do this from shell because I have a few thousand objects

from app.models import Entry

I tried:

Entry.objects.filter(len(zip_code)==4).update("0"+zip_code)

and

Entry.objects.filter(len(zip_code)==4).update(f("0"+{zip_code}))

Error returned:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'zip_code' is not defined
moken
  • 3,227
  • 8
  • 13
  • 23
PolarBear
  • 97
  • 5

1 Answers1

0

You could make a migration for that:

first, create an empty migration:

python manage.py makemigrations your_app_name --empty

in that newly created migration, define your function:

def update_zipcodes(apps, schema):
    YourModel = apps.get_model("your_app_name", "YourModel")  # django will retrieve your model here
    
    for obj in YourModel.objects.all():
        if len(obj.zip_code) == 4:
            old_zip_code = obj.zip_code
            obj.zip_code = f'0{old_zip_code}'
            obj.save()

Then call that function in the list operations (at the bottom of the file). your list should look like this

operations = [
    # migrations.RunPython.noop can be replaced here with a reverse function
    # (in case you want to "un-apply" that migration later for some reason)
    migrations.RunPython(update_zipcodes, migrations.RunPython.noop),
]

finally, you apply your migration by calling :

python manage.py migrate
Nour SIDAOUI
  • 164
  • 5
  • I'm still new to Django/Python, didn't understand your solution, can you please show me an example? To give you more context, model field zip_code is a CharField, most values are already 5 characters, only want to change values with 4 characters – PolarBear Dec 27 '22 at 01:59
  • I edited the answer, hope it helps ;) – Nour SIDAOUI Dec 27 '22 at 02:22
  • Got this error: TypeError: update_zipcodes() takes 1 positional argument but 2 were given. I added a second parameter to the function and it worked: def update_zipcodes(apps, get_model):. Thank you, much appreciated! If I ever needed to unapply something similar in the future. how would I do that? – PolarBear Dec 27 '22 at 07:13
  • as you said, a second parameter is required `schema` (I added it to the answer). If the answer is okay with you, kindly accept it so it gets marked as solved. regarding the reverse function, you can imaging applying the opposite of that function (loop over all zip_codes > remove those with a leading zero > save > add it as a second parameter in operations) and to call it you'll need to migrate to the previous migration > django will then unapply this one you can check this thread => https://stackoverflow.com/questions/32123477/how-to-revert-the-last-migration – Nour SIDAOUI Dec 27 '22 at 12:25