Devkev Devkev - 5 months ago 32
Python Question

Django reverse foreign key in admin

I have a Django related question about foreign keys in the admin panel. I'm facing the following situation:

class Driver(models.Model):
name = models.CharField(max_length=200)
executable = models.CharField(max_length=200)

class Device(models.Model):
name = models.CharField(max_length=200)
bound_driver = models.ForeignKey(Driver)

class DriverAssignment(models.Model):
device = models.ForeignKey(Device)
driver = models.ForeignKey(Driver)


Every device needs to have a bound driver (which it uses). DriverAssignment should be the table which shows which driver can be used by which device. So one device can have multiple possibilities of drivers which can be bound. Now i would like to have a dropdown on my admin panel showing all possible drivers for a specific device to select the 'bound_driver'.

How can i do this in Django? This is probably an easy thing for an experienced Django guy. I hope someone can give me a hint since i'm kind of new to Django. Thanks a lot!

Answer

Change your model Structure to This:

class Driver(models.Model):
    name = models.CharField(max_length=200)
    executable = models.CharField(max_length=200)

class Device(models.Model):
    name = models.CharField(max_length=200)
    bound_driver = models.ForeignKey(Driver, related_name="bound_to")
    available_drivers = models.ManyToManyfield(Driver)

ManyToManyField would do the same work as DriverAssignment Table.

You can add Available drivers in Available drivers field.

But then You would also Want that bound_driver is one of the Available Drivers. This validation you will have to do in forms. For that you have to over-ride Admin forms. See links

Links of Reference:

ManytoMany field: https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ManyToManyField

Model Admin (to over-ride admin functionality): https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#modeladmin-objects

You will have to spend some time reading and implementing if you want ot learn more. :)

OR

If you want to go with the same structure, than you will have to over-ride the form in ModelAdmin see here and Provide you custom form, which will be something like this:

class CustomForm(ModelForm)
  bound_driver = forms.ModelChoiceField(queryset = <your custom queryset that returns only available drivers>, ...)
  class Meta:
    model = Device

https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form