Opened 5 years ago

Closed 5 years ago

#31146 closed Bug (invalid)

ManyToManyField with a through table are not updated on save in admin when using inlines.

Reported by: Maximilian Owned by: nobody
Component: contrib.admin Version: 3.0
Severity: Normal Keywords: m2m ManyToManyField db Database update through
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

These are my admin models

class IngredientInlineAdmin(admin.TabularInline):
	model = Ingredient
	extra = 0
	fields = ('material', 'menge', 'unit', 'cost')
	readonly_fields = ["cost"]

class MaterialAdmin(admin.ModelAdmin):
	list_display = ('name', 'lieferant', 'costpkg')
	fieldsets = [
	("Name",{"fields":["name"]}),
	("Lieferant",{"fields":["lieferant"]}),
	("Kosten",{"fields":["costpunit","unit","menge","costpkg"]}),
	]
	readonly_fields = ["costpkg"]

class RecipeAdmin(admin.ModelAdmin):
	list_display = ('name', 'cost')
	inlines = (IngredientInlineAdmin,)
	fields = ('name', 'cost')
	readonly_fields = ["cost"]

	def save_related(self, request, form, formsets, change):
	    super(RecipeAdmin, self).save_related(request, form, formsets, change)
	    recip = form.instance
	    recip.cost = 0
	    recip.save()

class IngredientAdmin(admin.ModelAdmin):
    fields = ('material', 'menge', 'unit', 'cost', 'recipe')
    readonly_fields = ["cost"]

These are my real models

class Material(models.Model):
	UNITS = [
        ('kg', 'kg'),
        ('g', 'gramm'),
        ('l', 'liter'),
        ('stk', 'Stuck'),
        ('dkg', 'deka'),
    ]
	name = models.CharField(max_length=200)
	unit = models.CharField(max_length=20, choices=UNITS, default="kg", verbose_name="Einheit")
	lieferant = models.ForeignKey(Lieferant,default=1, verbose_name="Lieferant",on_delete=models.CASCADE, null=True)
	costpunit = models.FloatField(verbose_name="Stuckpreis")
	menge = models.FloatField(default=1,verbose_name="Menge")
	costpkg = models.FloatField(editable=False, verbose_name="Kilopreis") 
	
	class Meta:
		verbose_name_plural = "Materialien"

	def __str__(self):
		return self.name

	def save(self):
		if self.unit and (self.unit is not "stk"):
			kilogramms = convert_SI(self.menge, self.unit, "kg")


		self.costpkg = self.costpunit/kilogramms
		super(Material, self).save()



class Recipe(models.Model):
	name = models.CharField(max_length=200)
	cost = models.FloatField(default=1, editable=False, verbose_name="Kosten")
	ingredients = models.ManyToManyField(Material, through='Ingredient') 
	
	def __str__(self):
		return self.name 

	def save(self):
		x = 0
		for ing in Ingredient.objects.filter(recipe=self):
			x += ing.cost
		self.cost = x
		super(Recipe, self).save()


class Ingredient(models.Model):
	UNITS = [
        ('kg', 'kg'),
        ('g', 'gramm'),
        ('l', 'liter'),
        ('stk', 'Stuck'),
        ('dkg', 'deka'),
    ]
	material = models.ForeignKey(Material, default=1, verbose_name="Material", on_delete=models.CASCADE, null=True)
	recipe = models.ForeignKey(Recipe, default=1, verbose_name="Recipe", on_delete=models.CASCADE, null=True)
	menge = models.FloatField(verbose_name="Menge")
	unit = models.CharField(max_length=20, choices=UNITS, default="kilo", verbose_name="Einheit")
	cost = models.FloatField(default=1, editable=False, verbose_name="Kosten")

	def __str__(self):
		return self.recipe.name + ": " + self.material.name 

	def save(self):
		if self.unit and (self.unit is not "stk"):
			kilogramms = convert_SI(self.menge, self.unit, "kg")

		self.cost = kilogramms*self.material.costpkg
		super(Ingredient, self).save()

So my problem is when i change a material it isn't carried through the ingredient table to the recipe table

Change History (1)

comment:1 by Mariusz Felisiak, 5 years ago

Component: Database layer (models, ORM)contrib.admin
Resolution: invalid
Status: newclosed
Summary: When using the ManyToMany Field with a through table the db entries are not updated on save in admin when using inlineManyToManyField with a through table are not updated on save in admin when using inlines.

ManyToManyField's using the through argument work properly with admin (see documentation). It's probably some issue in your code.

Closing per TicketClosingReasons/UseSupportChannels.

Note: See TracTickets for help on using tickets.
Back to Top