1

First
I love Django, I like it because with just few lines of describing Model I get full CURD web app.
Now I am having app that need one-to-many relationship and it is not working as I am expecting.

I question is based on: How to express a One-To-Many relationship in Django

So this is my code:

models.py

from django.db import models

class Dude(models.Model):
    name = models.CharField(blank=False, null=False, max_length=100, unique=True)

    def __unicode__(self):
            return u"%s" % self.name

class PhoneNumber(models.Model):
    dude   = models.ForeignKey(Dude)
    number = models.CharField(blank=False, null=False, max_length=100, unique=True)

admin.py

from django.contrib import admin

from TestingDjango.apps.one_to_many.models import Dude, PhoneNumber

class DudeAdmin(admin.ModelAdmin):
    pass
    list_display  = ('name',)

class PhoneNumberAdmin(admin.ModelAdmin):
    pass
    list_display  = ('dude', 'number')

admin.site.register(Dude, DudeAdmin)
admin.site.register(PhoneNumber, PhoneNumberAdmin)

When I operate admin web UI I need to add Dude and after that I need to go to PhoneNumber, and for each number for same dude I need to add new row (and select same dude again and again).

What I was expecting was following: - when I am addend new dude, in same page, I will have "+" button where I could add multiple numbers for one dude. And after that click save. When I look at dude I will see all numbers for that dude, now I need to go to PhoneNumber to see all numbers per dude.

How to do it ?
Is it even possible with just editing admin.py or I need to write my own view for that ?
If I need to write my own view for that, please give some guidelines how to do it ?

Community
  • 1
  • 1
WebOrCode
  • 6,852
  • 9
  • 43
  • 70
  • You can use `Inline Models` for this. https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin They are exactly what you need. – Mp0int Nov 30 '13 at 11:48

1 Answers1

1

You can use InlineAdmin

In your admin.py

class PhoneNumberInline(admin.TabularInline):
    model = PhoneNumber   # related model
    extra = 1  # number of new record fields

class DudeAdmin(admin.ModelAdmin):
    inlines = [PhoneNumberInline, ]

admin.site.register(Dude, DudeAdmin)

This will display all related PhoneNumber records under the Dude record adn you can add new or update or delete existing records. That is all in a single page as you want. Documentation is here . In this approach, you do not need to add PhoneNumber directly to your admin.

Update: You can see related phone numbers or how many phone numbers are recorded to there. First you must define a method that will return phone numbers (or number of phones) to your Model

class Dude(models.Model):
    name = models.CharField(blank=False, null=False, max_length=100, unique=True)

def list_phones(self):
    phone_numbers = self.phonenumber_set.values_list('number', flat=True)  # use reverse relation to get a list ofall recorded numbers
    phone_count = self.phonenumber_set.count()
    return "This user have %s numbers recorded: %s" % (phone_count, ', '.join(phone_numbers))

def __unicode__(self):
        return u"%s" % self.name

And in your ModelAdmin

class DudeAdmin(admin.ModelAdmin):
    list_display  = ('name', 'list_phones')

You can use methods defined under your Model just as model fields.

Mp0int
  • 18,172
  • 15
  • 83
  • 114
  • Just one more thing, is it possible to add inlines = [ PhoneNumberInline, ] somehow to list_display = ('name',) of Dude so that I can see all the phones per dude. Or at least how many are phones there, or first N phones ? Thanks – WebOrCode Nov 30 '13 at 12:15
  • I have continuation of this question on http://stackoverflow.com/questions/20312209/how-to-add-button-in-django-admin-when-using-one-to-many-relationship-if-tha. Maybe you can help me again ? Thanks – WebOrCode Dec 01 '13 at 12:43