Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin: update inline based on other inline

Hi,

In admin panel I have created form for adding Product. Form includes 2 inline formsets as there are some models related to Product. User can create Product, then define variations of that product which different attributes. I`ll illustrate this with example. User has a t-shirt of one brand in 3 different colors and want to add them with different prices. T-shirt is created as Product with 3 Variations.

class Detail(models.Model):
    product = models.ForeignKey('Product')
    attribute = models.ForeignKey('Attribute')
    value = models.CharField(max_length=500)

class Attribute(models.Model):
    name = models.CharField(max_length=300)

class Variant(models.Model):
    product = models.ForeignKey(Product)
    details = models.ManyToManyField(Detail)
    quantity = models.IntegerField()
    price = models.DecimalField(max_digits=6, decimal_places=2)

I omitted Product as it is irrelevant.

class DetailInline(admin.TabularInline):
    model = Detail

class VariantInline(admin.StackedInline):
    model = Variant

class ProductAdmin(admin.ModelAdmin):
    class Meta:
        model = Product

    inlines = [DetailInline, VariantInline]

This works nicely, models are saved fine, I do have a problem with Variants inline. Variants inline display Detail objects but only ones already saved in database. In order to make life of user easier best would be to add Detail objects to Variant inline when Detail objects are created, so it would have to happen before Product is saved.

  • Is there a way to manually refresh Inline with values?
  • Is there a mid-save I could use to create Detail objects but not Product and get back with results?
  • Should model be redesigned? (I really do not want to do this, unless I have to)
  • Is there different workflow that user would need to follow to add product?

I have tried to inject entries into inline by using js but this is hackish and Django did not validate formset with fake values throwing error that wrong value had been selected.

Final thoughts that came to my mind while I was writing this question. It is possible to create js that in case if Inline form of Object is altered would pass data to custom view that would create objects and get back with results. One problem that I see (beside it does not feel right) is how to inform django that new objects were created so it won`t raise an error about non existing values.

Anyway I hope someone will understand this long question.

like image 769
Michał Klich Avatar asked Feb 18 '13 20:02

Michał Klich


1 Answers

One thing that comes to mind is Knockout.js.

It's very good at keeping lots of elements in the DOM updated at the same time, and you could easily push new values back to your custom view with Ajax calls from client-side events.

There are several frameworks that can do this, but I think that Knockout is one of the easier to read and implement of the most popular ones like Backbone, Angular, Ember, etc.

Django will typically complain about dynamically added choices, but as long as they exist server-side when the form is validated, you should theoretically be alright.

like image 172
Brandon Avatar answered Sep 20 '22 13:09

Brandon