Le pont entre Python et ReactUn hibou est un nano-cadre qui peut être intégré à d'autres cadres.
Image de sova.online, sur laquelle 3 serveurs http fonctionnent:
http://sova.online/ - juste Falcon
http://sova.online:8000/ - juste Django
http://sova.online:8001/ - juste Python (login: 1, mot de passe: 1)
Il existe des codes source et des instructions d'installation. Il n'y a pas de publicité là-bas.

L'idée de créer des sites en Python avec un rendu sur React n'est pas nouvelle. Il y a un merveilleux framework
https://plot.ly/products/dash/ , pourquoi faire autre chose?
Expliquez: Owl n'est pas conçu pour le développement de sites Web. Il s'agit d'un outil pour remplacer les clients lourds par des applications exécutées via le navigateur (applications de bureau).
- Qu'est-ce qu'un client Web?
- Non. Ce n'est pas un client Web. Ceci est une application de navigateur.
"Je ne comprends pas."
- Malheureusement, de nombreux développeurs ne comprennent pas.
En tant que général, j'ai travaillé activement avec plusieurs applications Internet.
Client en ligne de la banque Ugra (la banque est fermée).C'était une bonne application, mais c'était une applet Java, c'est-à-dire client lourd lancé depuis le navigateur. Et la banque d'Ugra, et les applets dans le passé.
Client en ligne de la banque VTB-24 (la banque est fermée).Je suis un humaniste, mais après avoir travaillé avec ce miracle, des pensées cruelles ont commencé à apparaître telles que: "Forcer le développeur à y enregistrer 1000 chèques de paie".
De plus, en tant que client web, il est beau. L'animation s'ouvre sur un téléphone portable. Ouah! Cool!
J'ai demandé à un ami comptable: comment travaillez-vous avec lui?
Elle dit: super! Je charge les données en 1s, en 1s je travaille, je télécharge les résultats.
Client en ligne SberbankClient satisfaisant, vous pouvez travailler. Quand on m'a demandé de le noter, je lui ai donné 3 points sur 5 et je lui ai donné une liste de commentaires. C'est avec mes 10 paiements par mois. Ceux qui font 100 factures par jour sont susceptibles de télécharger des informations.
Remplir un paiement.

La zone verte, qui occupe 20% de l'écran, est le menu. Il n'interfère pas seulement (position: fixe), il dit que le développeur n'est pas un professionnel. Si j'ai commencé à créer un paiement, l'écran devrait l'être. 3 boutons: "Créer", "Enregistrer comme modèle", "Annuler". Ces boutons sont (pour une raison ci-dessous). Ce n'est pas un SPA de plusieurs pages: si vous cliquez sur l'élément de menu, les données du formulaire seront perdues.
Celui qui l'a fait ne comprendra même pas ce qu'est la frappe: «Normalement, tout le monde le fait, une telle bibliothèque, les gens travaillent ...». Et il a raison. Vous devez demander au gestionnaire de projet, et pour le gestionnaire, l'essentiel est les bases de données et les couches dans le modèle conceptuel. Et les formulaires - nous embaucherons des garçons, ils dessineront. Et ils sont probablement fiers de ce hack.
Salles de marché (5 pièces, 44 lois fédérales)Ce sont vraiment des applications (pas des clients Web). Mais je n'aime pas les contrôleurs de terrain.
Exemples:

Il est étrangement aligné, la largeur du champ est clairement insuffisante, il n'y a pas d'auto-hauteur dans le champ de saisie.
Un autre exemple. Il n'y a pas de modèle jj.mm.aaaa dans le champ «Date de publication», le calendrier est en erreur, l'icône du calendrier fait peur:

Liste sur rts-tender: il y a l'entrée actuelle surlignée en couleur, les flèches peuvent se déplacer dans la liste, mais il n'y a pas de défilement automatique (vous pouvez fuir la bordure de l'écran), ni Enter ni la barre d'espace n'ouvrent le lien, l'onglet n'est pas attaché à l'enregistrement en cours. Bien que vous ne puissiez ouvrir le lien qu'avec la souris, j'évalue le contrôle avec un signe plus. Une telle fonctionnalité (mémoriser et mettre en évidence le document actuel) ne me suffit pas dans mail.ru
Cela ressemble à de petites choses. Mais l'application professionnelle diffère du semi-professionnel dans les détails. L'utilisateur final ne se soucie pas de la base de données dont vous disposez et du nombre de couches dans le modèle conceptuel. Il fonctionne avec des formes d'écran et a 3 exigences: fonctionnel, pratique, rapide.
Malheureusement, le choix du système est déterminé par des informaticiens et des patrons qui eux-mêmes n'ont pas travaillé avec le système et ne fonctionneront pas. Ils apprécieront la vitesse, ils apprécieront la fonctionnalité telle qu’ils la comprennent, et ils ne se soucient pas de la commodité, surtout, d’être beaux.
Pavel Valeryevich Durov n'a inventé ni un réseau social ni un messager. Il a fait ce dont les utilisateurs avaient besoin, commodément et magnifiquement. Et les gens ont apprécié cela, y compris financièrement.
Owl est un outil pour construire une interface professionnelle.
Qu'est-ce que cela signifie, par exemple, EDMS.
Il y a un EDMS, il a 3 groupes d'utilisateurs:
Supérieurs
Spécialistes en préparation de documents
Commis de bureau.
Patrons, ils sont comme des enfants. Ils doivent être simples et beaux. Idéalement 1 bouton et 1 champ. Et pour en montrer un peu plus. Un client Web et, bien sûr, un client mobile pour se montrer.
Spécialistes. Client Web, cross social network / mailer. N'oubliez pas qu'il existe de nombreux spécialistes et qu'ils doivent être formés. Plus l'environnement leur sera familier, mieux ce sera. Le client mobile sera également utile si le service de sécurité le permet.
Commis de bureau. C'est là que le hibou est utile. Les commis de bureau sont un groupe d'utilisateurs formant le système. Tout le monde peut tomber malade / partir en vacances / cesser de l'utiliser - l'EDMS fonctionnera. Si l'inscription s'arrête, tout ira bien.
Le travail de bureau est un convoyeur, et ici tout est important, toute petite chose: polices, demi-teintes, remplissage automatique, vérification des valeurs, facilité de saisie, etc.
EDS "Case". Les bureaux des interprètes se font sur le client web, le bureau est un gros client. Tout va bien, mais cela fonctionnera jusqu'à ce que le gouvernement interdise Windows aux agences gouvernementales. J'adore Win 7, mais si j'étais le dirigeant, le marché informatique était revigoré avec de nouvelles commandes et MS restait en mémoire. Soit dit en passant, le 6 décembre, Anton Siluanov a signé une
directive sur la transition vers les logiciels nationaux.
Sova.onlineComment un hibou ouvre un formulaire.
Sans multi-page.
L'élément central de la Chouette est le composant Document. En appuyant sur ctrl-U sur la page de démarrage, vous verrez tout ce dont vous avez besoin pour créer un objet de la classe Document:
- champs de données de la base de données;
- l'url du formulaire à afficher;
- dbAlias, unid - pour travailler avec la base de données;
- autre chose là-bas.
Dans une certaine mesure, Document est un analogue de la forme Redux.
Le formulaire est chargé en tant que chaîne JSON, puis l'ancien dictionnaire devient un objet ayant un style, className et un tableau (liste) d'éléments. Le tableau sera inséré dans l'élément avec id = root sous la forme
<div style className>……</div>
Les éléments de tableau sont des objets qui décrivent des balises.
<div>, <a>, <img>, <button>
ou un tableau ou des composants.
La fonction de boxe est responsable de l'analyse du tableau. Si un élément contenant un tableau est rencontré, il s'appellera récursivement.
Le nombril de la terre est bien sûr un div.
Dans le cas le plus simple, il s'agit d'une ligne: dict (div = 'Hello', className = 'h2')
Mais il peut y avoir un tableau (tableau de tableaux):
def style(**par): return {'style': {**par}} dict(
Il y a 3 panneaux (chacun dans un fichier séparé: subFormTop.py, etc.).
subFormTop.panel () renvoie un tableau pour construire le panneau supérieur.
subFormLeft.panel () et subFormRight.panel () sont combinés en une chaîne ('className': 'row') et décrivent les panneaux gauche et droit.
subFormDown.panel () est mis en commentaire (inutile).
Cela peut sembler compliqué. Mais c'est Python: tout peut être simplifié.
Un exemple de formulaire de la revue «Reports». La fonction labField (label, DB_field_name) renvoie un tableau de deux dictionnaires (ligne de table): le premier dictionnaire est {'div': label}, le second {'field': [DB_field_name, 'tx']}.
div = [ docTitle(''), dict ( wl='40mm', className='cellbg-green', div=_table( labField('', 'nodafd'), labField(' ', '_STARTINGTIME'), labField('', '_ENDTIME'), labField('', 'CREATOR'), labField('', 'REPORTCAT'), labField('', 'REPORTNAME'), labField('', 'REPORTTITLE'), labField(' ', 'dt1'), labField(' ', 'dt2'), labField(' 2', 'dt3'), labField(' 2', 'dt4'), labField('', 'LBYEARS'), labField('', 'GRGROUP'), labField(' ', 'QUERYMAIN'), labField('', 'NOTES'), )), sent(), ]

Exemples de sova / api / forms / home / top.py (à partir de sova.online):
dictionnaire python
{'a': 'React v16', 'href': 'https://reactjs.org'}
Génère un composant React clair
<a href={'https://reactjs.org'}>React v16</a>
Img est plus intelligent que la norme - dans les accessoires, vous pouvez spécifier href et target:
Python:
dict (img = 'image? react.ico', style = {'width': 16}, href = 'https: //reactjs.org')
Un fragment d'un analyseur qui convertit un tableau d'objets en composants (boxing.js):
if ( td.img ) {
Tapez dans le moteur de recherche "réagir bibliothèque de composants". Le résultat est prévisible - beaucoup. Mais toute cette abondance concerne les sites Web, pas les applications:
Smart-textarea est peut-être le seul contrôle qui me convenait.
React-select - simplifié et refait la liste déroulante
Sélecteur de données / calendrier - n'a rien trouvé de convenable. Il a écrit le sien, en prenant comme exemple le G.Chrome intégré.
Upload / Download - rien de convenable, a écrit le mien.
À mon humble avis: les sites Web ont un triste avenir. La grande majorité des utilisateurs dans un proche avenir cessera d'utiliser des navigateurs (ou déjà arrêté). Le téléphone grandira avec la tablette et 1 tableau de bord de 10 applications répondra pleinement aux besoins.
J'ai déjà rencontré deux fois des programmeurs qui ne savent pas écrire correctement une adresse e-mail. Pourquoi devraient-ils se souvenir de ce qu'ils n'utilisent pas? Le monde change.
Dans Owl, les contrôleurs ne sont pas parfaits, mais ils ont été conçus pour l'opérateur, pas pour l'internaute.
A titre d'exemple, le formulaire «Transfer Mark». Une forme assez universelle, utilisée lorsqu'il y a un boss. Les champs qui contrôlent le masquage sont entourés de rouge dans la capture d'écran. Les résolutions supplémentaires s'ouvrent automatiquement au fur et à mesure qu'elles sont remplies, si dans le dispositif il y a plusieurs instructions à différents groupes d'artistes avec des termes différents. Deux mandats par groupe: 1er mandat au 1er interprète, 2e mandat aux co-exécuteurs.

Vous pouvez toucher le formulaire
ICIUn contrôleur est un composant React associé à un champ de base de données.
Une description détaillée des contrôleurs avec la possibilité de vérifier leur fonctionnement est sur Sova.online.
Faites attention aux types rtf et json. Rtf est affiché sous forme de texte, mais s'il y a une construction {_ {object} _} dans le texte, Owl exécutera json.parse pour cette construction et ajoutera le résultat au formulaire. Un champ de type json doit stocker une description du tableau des éléments de balisage: [{ele1}, {ele2}, ...]. json.parse est exécuté avant le rendu.
Les champs avec ces types vous permettent de stocker le balisage dans la base de données ou dans des fichiers. Utile pour créer des rapports et rédiger de la documentation.
La liste des contrôleurs pour tous les types de champs (controllers.js):
export const controller = prop => { switch (prop.type) {
Une application nécessite un mécanisme de manipulation des contrôleurs.
Dans un hibou, tous les contrôleurs de documents sont stockés dans une variable de document
this.register
Je n'ai pas osé utiliser les références à cause des rumeurs selon lesquelles la rédaction allait l'annuler.
Le contrôleur peut avoir les interfaces suivantes:
getValue (param)
setValue (valeur, param)
setFocus ()
changeDropList ()
Afin d'accéder au champ souhaité, il existe des méthodes documentaires
getField (fieldName, param)
setField (fieldName, value, param)
changeDropList (fieldName, param)
setFocus (fieldName)
Pour les champs de type FileShow, il existe une méthode fileShow ['FILES1 _']. HasAtt (), où FILES1_ est le nom de la zone de fichier. Renvoie vrai s'il y a des pièces jointes. Dans la marque de transfert de ces zones 2.
Les contrôleurs peuvent générer un événement de recalcul. Si un gestionnaire est enregistré pour ce champ, il s'exécutera. Les gestionnaires sont situés dans des fichiers js chargeables.
Un exemple et une description quelque peu simplifiée:
Il existe un formulaire «Transfer Mark» (o.py). Il contient le fichier o.js chargé
Dans o.js, les gestionnaires sont enregistrés
recalc: { PROJECTO: doc => doc.forceUpdate(), WHOPRJ2: doc => doc.forceUpdate(), WHOPRJ3: doc => doc.forceUpdate(), … }
, et des conditions de masquage sont également spécifiées (project, op, prj1, prj2 ... prj5 est la propriété "name" dans la description des divs):
hide: { project: doc => !doc.getField('projectO'),
Comment ça marche: le champ PROJECTO est une case à cocher, lorsque la valeur est modifiée, le contrôleur génère un événement recalc, le document appelle le gestionnaire recalc.PROJECTO (this).
Le gestionnaire appelle simplement forceUpdate () pour redessiner le document.
Lors du redessin, il est vérifié si le composant dans les accessoires a un nom, s'il existe une fonction de masquage [props.name] pour ce nom et s'il renvoie true.
prj3: doc =>! doc.getField ('projectO') || (! doc.getField ('whoPrj2') &&! doc.getField ('whoPrj3'))
Masquez la troisième résolution (zone avec props.name === 'prj3') si la case à cocher 'projectO' est désactivée ou si les exécuteurs ne sont pas entrés dans les champs de résolution 2 et 3 (les champs 'whoPrj2' et 'whoPrj3' sont vides).
Le nom de champ lors de l'appel de fonctions est insensible à la casse.
WHOPRJ2 est une zone de liste déroulante; lorsque vous sélectionnez une valeur, le contrôleur génère également un événement de recalcul, ce qui entraîne également un redessin. En choisissant un artiste dans la deuxième résolution, vous ouvrirez ainsi la troisième.
Dans les fichiers js chargés, vous pouvez:
- gérer la dissimulation;
- gérer uniquement la lecture;
- répondre aux changements de terrain;
- exécuter des commandes de bouton;
- faire la validation des champs et des formulaires avant l'enregistrement;
Téléchargez le fichier pour le formulaire 'fo':
window.sovaActions = window.sovaActions || {}; window.sovaActions.fo = {
Validation des champs - une fonction qui renvoie vide si tout va bien, ou un message sur ce qui ne va pas. Un hibou mettra l'accent sur un champ invalide.
Validation du formulaire - Promesse. Dans l'exemple, il n'y a pas de vérification (oui est toujours appelé), juste quelque chose est fait avant l'envoi au serveur.
Dans la validation sous forme de redux se fait par trow - une sorte de sauvage.
Pour ceux qui ne connaissent pas les promesses, un exemple des plus simples: const confirmDlg = msg => new Promise((ok, cancel) => confirm(msg) ? ok(' ') : cancel(' cancel')); confirmDlg(' ') .then( s => console.log(s)) .catch( s => console.log(s));
La classe Document possède plusieurs commandes prédéfinies qui peuvent être utilisées dans les boutons:
modifier: passer en mode d'édition de formulaire
enregistrer: enregistrer le formulaire
fermer: fermer le formulaire
saveClose: enregistrez et fermez le formulaire
prn: imprimer un formulaire avec le choix d'un modèle pour l'impression
docOpen: ouvrir un document
dbOpen: ouvrir le journal
xopen: ouvrir l'url
newDoc: créer un nouveau document avec le formulaire souhaité
Dans Redux-form api est plus riche, dans Owl seulement ce qui est nécessaire
Multi-page.La classe Document crée un objet (formulaire) qui est incorporé dans un élément.
<div id="root"></div>
.
Nous l'appellerons le «document racine». Si vous ajoutez un élément au document racine
<div style = {{position: 'absolute', zIndex: 999}} />, vous pouvez également y insérer un autre objet Document.
Que faire avec les gestionnaires de commandes chargeables? C'est simple: chaque formulaire a son propre gestionnaire (ses propres js), et le document racine doit charger ceux qui peuvent être requis.
Exemple pour la page de démarrage sova.online (home.py)
Le formulaire home.py, afin de démontrer la nature de plusieurs pages, ouvre des documents avec les formulaires «rkckg», «outlet», «outlet.gru», «o».
Pour que tous les formulaires fonctionnent correctement, vous devez enregistrer des scripts pour ces formulaires dans home.py:
javaScriptUrl = ['jsv?api/forms/rkckg/rkckg.js', 'jsv?api/forms/outlet_gru/outlet_gru.js', 'jsv?api/forms/outlet/outlet.js', 'jsv?api/forms/o/o.js', 'jsv?api/forms/home/home.js']
Étant donné que lors de l'appel d'une fonction du gestionnaire, le premier paramètre transmet le lien vers le document, les actions seront effectuées avec le document souhaité.
OOP et pas de miracles.
Réagir - pas Réagir
J'ai déjà décrit le formulaire de rapport. Il s'ouvre à partir du gestionnaire de rapports (flèche "Réagir") et décrit les paramètres de collecte du rapport.

Les rapports eux-mêmes (flèche «pas réagir») sont stockés dans des documents subordonnés avec le formulaire «rapporter» sous forme de pièces jointes html. Nous étions engagés dans l'élaboration de rapports lorsque React n'était pas là, le formulaire «rapport» s'est avéré simple (20 lignes de html et 15 lignes de just-js), pourquoi changer ce qui fonctionne depuis 8 ans.
Ouvrez le Gestionnaire de rapports.Le formulaire de rapport se compose de 4 boutons et d'un iframe. Le hibou avant d'ouvrir le document remplace src = "" par la ligne url pour télécharger la pièce jointe html dans l'iframe, le navigateur fait le reste.
Les boutons EXCEL / WORD sont similaires: insérez les boutons d'URL pour le téléchargement avec le nom de fichier «report.html.xls» ou «report.html.doc» et le type MIME correspondant au bon endroit. Le reste est fait par Excel / Word («ces animaux intelligents comprennent parfaitement tout ce qu'ils attendent d'eux»).
Depuis do_get.py:
downloadUrl = '/download/' + fn + '?' + '&'.join([d.db.alias, d.unid, idbl, fsName, fzip, ctype, flen]) excel = '/download/%s.xls?%s' % (fn, '&'.join([d.db.alias, d.unid, idbl, fsName, fzip, 'application/x-excel', flen])) word = '/download/%s.doc?%s' % (fn, '&'.join([d.db.alias, d.unid, idbl, fsName, fzip, 'application/msword', flen])) html = html.replace('src=""', 'src="%s"' % downloadUrl).replace('openExcel', excel).replace('openWord', word)
Lors de l'ouverture html dans Excel / Word, il existe des différences avec le navigateur, mais elles sont petites. Et l'article ne parle pas de ça.
Faites une forme à partir de zéro.Données sources:
Il y a 3 fonctions
def snd (* msg, cat = 'snd'):
def err (* msg, cat = 'all'):
def dbg (* msg, cat = 'snd'):
, qui sont plus ou moins uniformément répartis dans le code et écrivent des messages d'erreur et autres conneries dans le fichier journal.
Le format du message est transmis à la journalisation, sous la forme:
'% (asctime) s% (levelname) s [% (name) s]% (message) s'
Le fichier est rempli de messages
...
09/02/2018 17:50:07 DEBUG [http-server] addr ('127.0.0.1', 49964), "GET / arm HTTP / 1.1" 200 -
09/02/2018 17:54:07 INFO [Espace libre] Les pièces jointes sont enregistrées dans ". \ DB \ files" Free 68557 Mb
09/02/2018 17:58:07 ERREUR [do_get.py] getScript: [Errno 2] Aucun fichier ou répertoire de ce type: 'sova / api / forms / o / oo.js'
...
Date-heure, puis niveau, puis entre crochets une catégorie à l'intérieur du niveau, puis un message.
Défi:
Créez une page pour afficher le fichier journal. Quel type

Nous appellerons le formulaire «lm», il sera formé par la fonction page dans le module api / forms / lm.py
def page(dbAlias, mode, userName, multiPage): return dict( style(background='url(/image?bg51.jpg)', backgroundSize='100% 100%'), div=[ dict( style(width='200px', float='left', background='rgba(210,218,203, 0.5)', padding='0 5px'), div=[ _field('type', 'list', [' |all', '|err', '|info', '|debug'], saveAlias=1, **style(margin='10px auto', width=170, height=110) ), _field('cat', 'list', 'TYPE_ALIAS|||api.get?loadDropList&logger|keys_{FIELD}', listItemClassName='repName', listItemSelClassName='repNameSel', **style(height='calc(100vh - 133px)', overflow='auto') ) ], ), _field('msg', 'fd', br=1, **style(overflow='auto', height='100vh', font='bold 12px Courier', background='rgba(255,255,255, 0.8)') ), ] )
Sur le côté gauche, il y a 2 champs, tous deux avec le type de liste: type et cat (type et catégorie de message).
À droite, un champ msg de type fd (forDisplayOnly).
Les types de messages sont écrits dans la description du champ (['All log | all', 'Errors | err', ...),
les catégories sont extraites par xhr du dictionnaire global avec un appel d'url délicat:
api.get? loadDropList & logger | keys_err renverra au format json un tableau (liste) de catégories du dictionnaire global. Quelque chose comme bien ('logger', 'keys_err').
Les messages sont générés lorsqu'un document est ouvert par la fonction queryOpen dans lm.py
def queryOpen(d, mode, ground): logParser() ls = well('logger_all', 'AL L') s = '\n'.join(reversed(ls)) d.msg = s d.type_alias = 'all'
logParser lit et analyse le fichier journal. Il décompose les résultats en plusieurs tableaux et les enregistre dans le dictionnaire global. Rien d'intéressant: 2 simples re et boucle d'itérateur.
Fonctions pour travailler avec le dictionnaire global:
toWell (o, key1, [key2]) - enregistrez l'objet «o» dans le dictionnaire global
bien (key1, [key2]) - prendre un objet du dictionnaire global par clé (par deux clés).
C'est suffisant pour le premier dessin. Afin de pouvoir afficher des messages du type et de la catégorie désirés, il est nécessaire de faire des js chargeables.
Dans lm.py, ajoutez la ligne
javaScriptUrl = 'jsv? api / forms / lm / lm.js'
et créez lm.js:
window.sovaActions = window.sovaActions || {}; window.sovaActions.lm = {
getLogData extrait les messages du serveur du type et de la catégorie souhaités:
def getLogData(par, un): lg, _, cat = par.partition('|') msg = well('logger_' + lg, cat) return 200, 'text/html; charset=UTF-8', '\n'.join(reversed(msg))
Vous pouvez profiter du formulaire
ICI .
Initialement, la journalisation a été effectuée sur la base du module de journalisation standard
en utilisant logging.FileHandler, .addHandler et autres getLogger et setFormatter.
Comment enseigner. Mais en même temps, c'était buggy. Vous pouvez lancer des pierres, mais lorsque j'ai lancé la journalisation et que je viens de commencer à écrire dans un fichier, le code est devenu plus court, plus compréhensible et les problèmes ont disparu.
Inclus est un serveur wsgi multi-thread auto-écrit avec autorisation Digest. Ce n'est pas pour les sites. Pourquoi avait-il besoin de lui?
Le client a 40 jur. personnes, dans la plupart des cas, 1-2-3 personnes travaillent avec le système. Le stockage de données sur Internet est interdit. Tous gagnent 7. Nécessite une facilité d'installation et de configuration.
Solution: en utilisant cx-Freeze et Inno Setup, nous réalisons le programme d'installation, l'exécutons sur l'ordinateur du plus responsable et obtenons un serveur mini-http pour le réseau local, en commençant comme un service Windows. Rien de plus. Vous ne pouvez pas utiliser le wsgiref.simple_server ou wsgi_Werkzeug intégré en Python, car ils sont monothread: alors qu'une demande échoue, d'autres attendent.
Il est peu probable que je surprenne quelqu'un en signalant que le Django WSGIServer / 0.2 CPython / 3.5.3 intégré est plusieurs fois plus rapide que le Python auto-écrit. Cela n'a pas d'importance - les formulaires et les répertoires sont mis en cache sur le client, seules les données de la base de données sont transmises très rapidement sur le réseau local.
Il y a une autre raison: l'application de bureau a accès aux ressources informatiques (signature numérique, fichiers, scanner ...). Afin d'obtenir le même accès depuis le navigateur, vous devez soit écrire un plug-in, soit raccrocher un petit serveur http dans les services, qui peut renifler depuis le serveur principal et effectuer les actions nécessaires sur la zone locale.
Le hibou n'utilise pas les outils de framework pour travailler avec la base de données. Dans le répertoire dbToolkit, quelque chose de similaire à la structure de MongoDB (ou Lotus Notes) dans SQLite3:
Classe de livre - db (dans la terminologie MongoDB et Lotus Notes)
Class DocumentCollection - une collection de documents du livre
La classe Document est un document (un objet contenant un nombre quelconque de champs).
Installation:Téléchargez
owl.zip depuis sova.online
L'archive contient le répertoire owl, à partir duquel vous pouvez exécuter le hibou à partir de django, falcon ou sans frameworks.
Téléchargez, décompressez.
Installer Python3 (3.5+)
1. hibou - sans cadres. Attention! Identifiant: 1, Mot de passe: 1
Linux:
cd ./owl
python3 wsgi_sova.py
ou dans une fenêtre séparée
écran -Udm python3 wsgi_server.py
Windows:
cd ./owl
wsgi_sova.py
2. Django
Linux:
Installez Django:
pip3 installer django
cd ./owl
python3 manage.py runserver
ou dans une fenêtre séparée
screen -Udm python3 manage.py runserver 127.0.0.1:8000
Windows:
Installez Django:
installer pip django
cd ./owl
manage.py runserver
3. faucon
Linux:
pip3 installer faucon
cd ./owl
python3 wsgi_sova.py falconApp: api 8001 log_falcon / falcon
Windows:
installer un faucon
cd ./owl
wsgi_sova.py falconApp: api 8001 log_falcon / falcon
**********************
- le titre de l'article est étrange, avez-vous compris ce qu'est "SPA multipage"?
- stratagème de commercialisation normal
- pourquoi sans Redux? Tout le monde utilise Redux.
- Je n'aime pas le mot "réducteur"
- mais sérieusement? ombineReducers à n'importe quel niveau de la hiérarchie ... C'est tellement beau
Est un multipage, bébé. Les gestionnaires de commandes doivent être à l'intérieur du formulaire, et non comme des cornes de cerf
- Pourquoi avez-vous même écrit un article?
- PR