Opened 7 years ago

Closed 7 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, 7 years ago

Component: Database layer (models, ORM) → contrib.admin
Resolution: → invalid
Status: new → closed
Summary: When using the ManyToMany Field with a through table the db entries are not updated on save in admin when using inline → ManyToManyField 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