Search code examples
djangodjango-3.2

How i can create a muti value filed without manytomany field in django?


I have a model:

class People(models.Model):
   family = models.CharField(null=True)
   phone_numbers = ?

How i can implement phone_numbers for some phone numbers. I think ManyToManyField is not a good idea for doing this.

What is best practice for this?

admin.py

class PhonesInline(admin.TabularInline):
    model = models.Phones

class PeopleAdmin(admin.ModelAdmin):
    inlines = [
        PhonesInline,
    ]
admin.site.register(models.People, PeopleAdmin)

Solution

  • What you can do is create a Phone model and create a Many-to-one relationship between Phone and People using ForeignKey. With this you can associate various phone numbers to a single person.

    class People(models.Model):
        family = models.CharField(null=True)
    
    
    class Phone(models.Model):
        number = models.CharField(max_length=15, unique=True)
        person = models.ForeignKey(People, on_delete=models.CASCADE)
    

    Now, for example, if you have a People instance in a variable called people, you can access its related phone numbers with values_list:

    people.phone_set.values_list('number', flat=True)
    

    As a note for your model, it's not recommended to use null=True to a CharField/TextField. The official Django documentation states the following:

    Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for “no data”: NULL, and the empty string. In most cases, it’s redundant to have two possible values for “no data;” the Django convention is to use the empty string, not NULL. One exception is when a CharField has both unique=True and blank=True set. In this situation, null=True is required to avoid unique constraint violations when saving multiple objects with blank values.

    You can also take a look at this question, which tackles my last point.

    Also I don't know which logic you want to apply to your project, but I think a better way to organize your models and their relationships is to create a Family class to deal with families like:

    class Family(models.Model):
        name = models.CharField(max_length=100)
    
    
    class People(models.Model):
        family = models.ForeignKey(Family, blank=True, null=True)
    
    
    class Phone(models.Model):
        number = models.CharField(max_length=15, unique=True)
        person = models.ForeignKey(People, on_delete=models.CASCADE)
    

    With this extra model you will be able to create another Many-to-one relationship between People and Family. Depending on your needs, you should adapt the arguments when creating the fields, the ones I provided are just an example.