0

I'm working on a dynamical object menu in my project (with django-simple-menu) and I have some questions in order to display this one after updated it. Especially reload the menu immediately after the update to display changes.

I have a simple model:

class MyModel(models.Model):
    """ A class to manage navbar menu of the application """
    collection = models.ManyToManyField('app.Collection', related_name='collection_list', symmetrical=False)
    application = models.ForeignKey('app.WebApplication', verbose_name=_('application'), related_name='application', on_delete=models.CASCADE)
    title = models.CharField(max_length=30, verbose_name=_('title'), default=('Xth Edition (Current)'))
    order = models.PositiveSmallIntegerField(default=1, verbose_name=_('menu order'), blank=True, null=False)
    display = models.BooleanField(verbose_name=_('Display menu'), default=True)

    class Meta:
        verbose_name = _('menu setting')
        verbose_name_plural = _('menu settings')

This model is handle by django-crud library.

Then I have a menu.py file containing:

class CustomMenu(Menu):
    def __init__(self):
        self.create_custom_menu()

    def create_custom_menu(self):
        qs_custom = MyModel.objects.filter(display=True).order_by('application', 'order')
        for menu in qs_custom:
            slug = slugify(menu.title)

            # children menu
            children = []
            for col in menu.collection.all():
                children.append(
                    CustomMenuItem(col.title, reverse('#')))

            self.add_item(slug, CustomMenuItem(menu.title, f'#{slug}', children=children))
        self.add_item('toto', MenuItem(_('Toto'), '#'))
        self.add_item('tata', MenuItem(_('Tata'), '#'))


Menu.add_item('home', MenuItem(_('Home'), '/home'))
CustomMenu()
Menu.add_item('content', MenuItem(_('Content'), '#content', children=content_children))
Menu.add_item('admin', MenuItem(_('Admin'), '#admin', children=settings_children))

The Menu class is available here.

My issue:

When I update my model (for example by checking boolean field to display the object), my object menu in navbar is not displayed immediately. I have to restart the server to take into account the change.

I tried to use signals:

@receiver(signals.post_save, sender=MyModel)
def auto_reload_menu(sender, instance, **kwargs):
     """ Reload menu after create or update menu object """
     ...

But I don't know if it's the right way and How I can actualize the menu.

Do you have any idea to do that ?

ChocoBomb
  • 301
  • 4
  • 15
  • what if you just reload the page? – Bernard 'Beta Berlin' Parah May 28 '19 at 18:03
  • @BernardParah Doesn't work, it's the main issue :/ I have to my mind to reload the menu with my function `CustomMenu` but I don't overcome to do that – ChocoBomb May 28 '19 at 18:05
  • You should add data in database table and read this data from database table/or just from file (JSON or something). – gachdavit May 28 '19 at 18:37
  • After refresh page menu will be shown, in your templates. Also, you need context processors to read data from templates from every view. – gachdavit May 28 '19 at 18:38
  • Also, when you add something in database update UI (Menu in your case immediately is a little hard task). You should implement something like real-time infrasturcure (read database in every N seconds(short-polling) or use long-polling or something similar). – gachdavit May 28 '19 at 18:40
  • @gachdavit I don't post context_processors according to menu but this menu is called on each template. But you're right, I need something which display menu in real-time. If I check `display` field, object should appear immediately in navbar. – ChocoBomb May 28 '19 at 18:45
  • Send ajax request every 5 seconds which checks database and renders updated menu (this is HTTP short-polling. Not best approach, but you can try on this step). – gachdavit May 28 '19 at 19:14
  • @gachdavit It's a solution, but it will spam the application by requests and decrease performance. I'm looking for other solutions. – ChocoBomb May 28 '19 at 19:21
  • Other solution is HTTP long-polling. Check this concept. Good luck ! – gachdavit May 28 '19 at 19:29

0 Answers0