ChatCrawlersearch across public Telegram Open the app
P

Python Daily Group

сообщение · 2026-08-03 15:30 UTC
I
u/admin.display(description='Status') def toggleswitch(self, obj): if obj.iscore: return formathtml( '<label class="module-toggle module-toggle--core">' '<input type="checkbox" checked disabled>' '<span class="module-togglelabel">Core</span>' '</label>', ) checked = 'checked' if obj.isenabled else '' return formathtml( '<label class="module-toggle" data-pk="{}">' '<input type="checkbox" {}>' '<span class="module-togglelabel">{}</span>' '</label>', obj.pk, checked, 'Enabled' if obj.isenabled else 'Disabled', ) Custom URL endpoint handles the POST, toggles is_enabled, clear the cache. Core modules get a disabled checkbox with a tooltip explaining why. I also disabled add/delete permissions on the Module admin — modules are created automatically, not manually. # Auto-sync with postmigrate New module appears in the database automatically. When you run migrate, a post\migrate signal fires and syncs the in-memory registry with the DB: def syncmodulesaftermigrate(sender, kwargs): registry = getregistry() if not registry: return for name, info in registry.items(): module, created = Module.objects.getorcreate( name=name, defaults={ 'label': info['label'], 'isenabled': True, 'iscore': info.get('iscore', False), 'urlprefixes': info.get('urlprefixes', ), 'dependencies': info.get('dependencies', ), }, ) if not created: # Update metadata but don't touch isenabled module.urlprefixes = info.get('urlprefixes', []) module.dependencies = info.get('dependencies', []) module.save() The important line is don't touch is\enabled. If the owner disabled ALPR last week, running migrate shouldn't silently re-enable it. Metadata gets updated, toggle state is preserved. # Per-client feature access Global module toggles solve "we don't want this feature at all." But what about "client X should have this, client Y shouldn't"? Each client get a ClientFeature record with boolean fields: class ClientFeature(models.Model): client = models.OneToOneField( Client, ondelete=models.CASCADE, relatedname='features', ) cabinet = models.BooleanField(default=True) bot = models.BooleanField(default=False) invoices = models.BooleanField(default=False) appointments = models.BooleanField(default=False) notificationstelegram = models.BooleanField(default=False) notificationswhatsapp = models.BooleanField(default=False) New client get only cabinet=True by default. Everything else is opt-in. The views check both layers — global module must be enabled AND client must have the feature. If either is off, access is denied. I know what you are thinking — "why not use django-flags or wafle or some other feature flag library." This system has maybe 10 modules and 50 clients. A full-blown feature flag framework would be like using a chainsaw to cut bread. The boolean fields are stupid simple, easy to understand in the admin, and they work. # What I learned The two-layer approach (global + per-client) covers 95% of cases. Global toggle for "this feature does not exists yet." Per-client toggles for "this client pay for premium features." Haven't needed anything more complex so far. post_migrate sync was worth the effort. Before this I had to manually create Module records when add a new app. Forgot once, the middleware let everything through because the module wasn't in the DB. Now it is automatic and I can not forget. Cache invalidation is the actual hard part. 60-second TTL is a lazy solution. If the owner disables a module and a request comes in at
4 ·

Вся лента

Каталог площадок Искать в ChatCrawler

A snapshot of an open public feed from the search index ChatCrawler — “Google for public Telegram”; refreshed as the venue is crawled. Times are UTC.

Public content only, official Telegram API. About · FAQ · What we do not do · Remove a page · Catalog