Need help please... Admin add item Field value from another ForeignKey

Dear Django Coders…

I’am a newbie at Django Coding…

i need help with the Django Admin - Add item Function…

i have this Model:

class MachineGroups(models.Model):
    group = models.CharField(verbose_name="Maschinengruppe", max_length=200, unique=True)
    added_date = models.DateTimeField("hinzugefügt am", auto_now_add=True)
    edited_date = models.DateTimeField("bearbeitet am", auto_now=True)

    def __str__(self):
        return self.group
    class Meta:
        verbose_name = "Maschinengruppe"
        verbose_name_plural = "Maschinengruppen"

class Machines(models.Model):
    name = models.CharField(verbose_name="Maschinenname", max_length=200, unique=True)
    group = models.ForeignKey(MachineGroups, verbose_name="Maschinengruppe", on_delete=models.PROTECT)
    added_date = models.DateTimeField("hinzugefügt am", auto_now_add=True)
    edited_date = models.DateTimeField("bearbeitet am", auto_now=True)

    def __str__(self):
        return self.name
    
  class Meta:
        verbose_name = "Maschine"
        verbose_name_plural = "Maschinen"

class MachineModules(models.Model):
    machine_module = models.CharField(verbose_name="Maschinenmodul", max_length=200, unique=True)
    machine_group = models.ForeignKey(MachineGroups, verbose_name="Maschinengruppe", on_delete=models.PROTECT)
    machine_name = models.ForeignKey(Machines, verbose_name="Maschine", on_delete=models.PROTECT)
    added_date = models.DateTimeField("hinzugefügt am", auto_now_add=True)
    edited_date = models.DateTimeField("bearbeitet am", auto_now=True)

    def __str__(self):
        return self.name
    class Meta:
        verbose_name = "Maschinenmodul"
        verbose_name_plural = "Maschinenmodule"

and this admin.py:

class MachinesAdmin(admin.ModelAdmin):
    fieldsets = [
        ("Maschinendaten", {"fields": ["name", "group"]}),
    ]
    list_display = ["name", "group", "added_date", "edited_date"]
    list_filter = ["group"]
    search_fields = ["name", "added_date", "edited_date"]

class MachineGroupsAdmin(admin.ModelAdmin):
    fieldsets = [
        ("Maschinendaten", {"fields": ["group"]}),
    ]
    list_display = ["group", "added_date", "edited_date"]
    search_fields = ["group", "added_date", "edited_date"]

class MachineModulesAdmin(admin.ModelAdmin):
    fieldsets = [
        ("Maschinendaten", {"fields": ["machine_name", "machine_module"]}),
    ]
    list_display = ["machine_group", "added_date", "edited_date"]
    search_fields = ["machine_group", "added_date", "edited_date"]

I can add items to Machines and MachineGroups normally. The MachineGroup is an select Field. That is fine.

Now i have implemented the MachineModules model.
If i want to add an MachineModel the Machine Field is an select field too. So far so good.
The only thing that i need is that the machine_group column gets the value from the assigned group from Machine because i don’t want to select the Group a second time.

If i add an MachineModule now i get the following Error:

(1048, "Column 'machine_group_id' cannot be null")

I know that the error is shown because an ForeignKey can not be null. But how can i assign the value from the group from the selected Machine to this field?

Can anyone help me please?

Many thanks in advance

Side note: When posting code (or templates, error messages, tracebacks, etc), enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.

ok thank you for the information. i will do this now

Almost perfect. The lines of ``` must be their own lines, they can’t be part of any other line. (No worries, I fixed that for you.)

It sounds like you don’t need to have machine_group as a field in this model, if the machine_group is determined by the group attribute of the related Machines.

I’d remove that field.

Thank you for fixing that. Now it looks much better :+1::grinning:

Unfortunately I need that field in this model because of further models in my app that I can get the full Information of Modules.

Do you have any idea how I get this to work? Or is it not possible with Django?

Thanks in advance

You can, by following the foreign key link in the related Machines object. There’s no need to replicate that information.

Aha ok. Can you show me an example how I can follow the ForeignKey please?

Best Thanks

If you have an instance of Machines named machine, how would you access the name field of that machine?

With machine.name i think? But how I get the group name if I only have an instance of Modules in modules? modules.group_name?

:thinking:

Absolutely correct.

So, along the same lines, machine.group is a reference to the MachineGroups instance by the foreign key.

Continuing along this same line, if you have an instance of MachineGroups named machine_group, then the reference to the group attribute would be machine_group.group.

So following this along through to the conclusion, if you have an instance of MachineModules named machine_module, then:

machine_module.machine_name.group.group
^^^^^^^^^^^^^^ Instance of MachineModules
               ^^^^^^^^^^^^^ ForeignKey to Machines
                            ^^^^^ ForeignKey to MachineGroups
                                  ^^^^^ CharField

Ok, that’s really nice :grinning::+1::grinning:

Thank you very much for the detailed description

You are the best :+1: