How to extend filed for existed table?

45 阅读1分钟

I have a User table and it already have some users.

Now I want to add a feature to let user upload their avatar image.

But how to save avatar field?

Method1: Add field on User table

I think this is a bad idea.If we want to add other ton of fields I think user table will be horrible😂.

But it doesn't need to much change and very easy to implement.

Method2: Add other table

Yeah User is django auth.models so I don't want to change it and avatar is user's some properity.So I will create a UserProfile table to save such as avatar, bio etc.

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(blank=True)
    avatar = models.FileField(blank=True, upload_to='user_avatar/')

Ofcourse we need to change some old code to render userInfo.But after that add other field will be easy and elegance😎.

You know what we have miss

User and UserProfile are 1to1 relation but now we have a lots of user but no UserProfile record yet.

GPT tell me to write a django custom command to set UserAvatar for the users whose doesn't has one.

# app/management/commands/create_user_profile_for_empty_user.py
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User
from discord.models import UserProfile

class Command(BaseCommand):
    help = 'Creates UserProfile for users who do not have one'

    def handle(self, *args, **options):
        for user in User.objects.all():
            try:
                UserProfile.objects.get(user=user)
            except UserProfile.DoesNotExist:
                UserProfile.objects.create(user=user)
                self.stdout.write(self.style.SUCCESS(f'Created UserProfile for {user.username}'))
(.venv)PS C:\projects\drf> python .\manage.py create_user_profile_for_empty_user
Created UserProfile for laoju
Created UserProfile for 1
Created UserProfile for 2
Created UserProfile for 3
Created UserProfile for 4
Created UserProfile for 5
(.venv) PS C:\projects\drf> python .\manage.py create_user_profile_for_empty_user
(.venv)PS C:\projects\drf> 

Then we need django signal to auto create UserProfile after a user is created.(Except you modify database directly)

from django.db.models.signals import post_save
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

Over.