There are such models:

class Item(models.Model): kind = models.ForeignKey(Kind, verbose_name="Тип предмета") price = models.IntegerField(default=0) class BuildingRequiredItem(models.Model): building = models.ForeignKey('Building', related_name="fk_required_items") item = models.ForeignKey(Item) count = models.IntegerField(default=0) class Building(Item): width = models.IntegerField() height = models.IntegerField() required_items = models.ManyToManyField(Item, through=BuildingRequiredItem, related_name='buildings_required', blank=True, null=True) 

Please tell me how you can do the following thing: I want to be able to add, delete, edit the list of required items for this building when editing the building parameters (pay attention to through, there is an extra field - count). I suspect that inline formsets can be used here somehow, but something doesn't work.

  • What have you tried that you can not? InlineModelAdmin tried? - neoascetic
  • InlineModelAdmin - what you need. And how to use it in your application, not in the admin? - djudman


1 answer 1

All the same, I think, look towards inlineformset_factory

 from django.forms.models import inlineformset_factory building = Building.objects.get(pk=1) BuildingRequiredItemFormSet = inlineformset_factory( Building, BuildingRequiredItem, fields=('item', 'count'), extra=3) BuildingRequiredItemFormSet(instance=building) 

In this case, you will need to select Item and specify the quantity. To avoid possible duplication of Aytems for one Building, add unique_together to BuildingRequiredItem.Meta

If you want all the Items to be output and you only need to fill in the count field, the output is something like this. I'm afraid of lying on my knees and I need to look for errors and optimize.

 class BuildingRequiredItemForm(forms.Form): building_pk = forms.IntegerField(widget=forms.HiddenInput()) item_pk = forms.IntegerField(widget=forms.HiddenInput()) count = forms.IntegerField() def save(self): data = self.cleaned_data bqi, created = BuildingRequiredItem.objects.get_or_create( building__id=data['building_pk'], item__id=data['item_pk'], ) bqi.count = data['count'] bqi.save() if bqi.count == 0: bqi.delete() BuildingRequiredItemFormset = formset_factory(BuildingRequiredItemForm, extra=0) building = Building.objects.get(pk=1) items = Item.objects.all() instance = [] for item in items: buildingrequireditem = building.buildingrequireditem_set.filter(item=item) if buildingrequireditem: count = buildingrequireditem[0].count else: count = 0 instance.append({ 'building_pk': building.pk, 'item_pk': item.pk, 'count': count}) 

As you can see, in the form item_pk. According to it, it will be necessary to display the name item before the count field.