当前位置:网站首页>Go language development Daily Fresh Project Day 3 Case - Press Release System II

Go language development Daily Fresh Project Day 3 Case - Press Release System II

2022-04-23 20:29:00 Programmation de jeux

1.Contenu lié au type

Avant de mettre en oeuvre les activités liées au type,Commençons par créer une table de type.Nous ajoutons ici la relation précédente de beaucoup à beaucoup.
Il y a beaucoup d'articles sous un seul type,Mais un article n'appartient qu'à un seul type,Donc l'article et le type appartiennent à un à plusieurs.
En même temps, nous analysons,Un utilisateur peut lire plusieurs articles,Un article peut également être lu par plusieurs utilisateurs,Il y a donc beaucoup à beaucoup de relations entre l'article et l'utilisateur.
Par conséquent,,On a commencé à construire des montres,Le Code de construction du tableau est le suivant:,Nous analysons un à plusieurs par Code,Comment définir plusieurs à plusieurs:

type User struct {    Id int    Name string `orm:"unique"`    Passwd string `orm:"size(20)"`    Articles []*Article `orm:"rel(m2m)"` //Définir des relations multiples à multiples}//Structure de l'articletype Article struct {    Id int `orm:"pk;auto"`    ArtiName string `orm:"size(20)"`    Atime time.Time `orm:"auto_now"`    Acount int `orm:"default(0);null"`    Acontent string `orm:"size(500)"`    Aimg string  `orm:"size(100)"`    ArticleType*ArticleType `orm:"rel(fk)"` // Définir une relation de un à plusieurs     Users []*User `orm:"reverse(many)"`  // Définir une relation inverse de plusieurs à plusieurs }//Tableau des typestype ArticleType struct {    Id int    Tname string `orm:"size(20)"`    Articles []*Article `orm:"reverse(many)"` // Définir une relation inverse d'un à plusieurs }func init(){    //1.Connexion à la base de données    orm.RegisterDataBase("default","mysql","root:[email protected](127.0.0.1:3306)/test?charset=utf8")    //2.Registre    orm.RegisterModel(new(User),new(Article),new(ArticleType))    //3.Générer des tableaux    //1.Alias de base de données    //2.Forcer les mises à jour    //3. Si le processus de création de table est visible     orm.RunSyncdb("default",false,true)}

D'après ce qu'on a appris sur les bases de données , Il existe plusieurs relations entre les tableaux et les tableaux ?Il y a généralement trois,Un contre un.,Un à plusieurs,Beaucoup à beaucoup, Mais ce qui est commun dans notre développement, c'est un à plusieurs et plusieurs à plusieurs , Nous nous concentrons ici sur ces deux , En savoir plus sur un à un .
orm Comment définir la relation entre deux tableaux ?
S'il y a une relation entre deux tableaux,ORM Associer deux tables en ajoutant un pointeur d'objet ou un tableau de pointeurs d'objet dans la structure correspondante des deux tables , Et ajouter les attributs correspondants aux champs pointeur d'objet et tableau de pointeurs d'objet , Par exemple, la table d'articles et la table de type ci - dessus appartiennent à un à plusieurs , Vous devez ajouter un type de pointeur d'objet à la structure de l'article , Puis définissez une à plusieurs relations ( orm:“rel(fk)” ),La même chose., Un tableau de pointeurs d'objets avec un article est nécessaire dans la table de type , Et définir une relation inverse d'un à plusieurs ( orm:“reverse(many)” ).

  • **Un contre un. ** Paramètres de la relation : Ajouter le pointeur de structure opposé dans les deux structures correspondantes , Et ensuite établir une relation individuelle ( orm:“rel(one)” ), La relation inverse est définie à orm:“rel(one)”

  • **Un à plusieurs ** Paramètres de la relation : La relation entre deux tableaux d'un à plusieurs n'est pas interchangeable , Prenons par exemple le tableau des articles et le tableau des types , Quand vous créez une table In Pointeur d'objet pour ajouter une table de type à la structure de l'article correspondant à la table d'article , Et de définir une à plusieurs relations ( orm:“rel(fk)” ), In Un tableau de pointeurs d'objets pour ajouter une table d'articles dans la structure correspondant à la table de type , Et définir une relation inverse d'un à plusieurs ( orm:“reverse(many)” ) Quand le tableau est généré , La base de données sera automatiquement Pour ajouter un tableau de type à un tableau d'article Id Comme clé étrangère pour la table des articles .Comme le montre la figure:

    GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No1Zhang.

    Une à plusieurs opérations d'insertion : Il suffit d'insérer un objet de type dans la table des articles .Les codes sont les suivants::

o := orm.NewOrm()article := models.Article{}artiType := models.ArticleType{Id:id}o.Read(&artiType)article.ArticleType = &artiTypeo.Insert(&article)

Une à plusieurs requêtes: ORM La requête inerte est par défaut lors de la requête Multi - tables , C'est - à - dire qu'il n'est pas explicitement indiqué de faire des requêtes Multi - tables , Même s'il y a une relation entre deux tables ,ORM Il n'y a pas non plus d'association entre deux tables . La fonction qui spécifie une requête Multi - tables est RelatedSel(). Le paramètre est le nom de la table à associer ,Il peut y en avoir plusieurs..Les codes sont les suivants::

count,err = o.QueryTable("Article").RelatedSel("ArticleType").Count()

Si le champ du tableau associé n'a pas de valeur , Donc les données ne sont pas disponibles

  • Beaucoup à beaucoup Paramètres de la relation : La relation entre deux tableaux est égale , Donc leurs paramètres de propriété peuvent appeler , Prenons par exemple la table des articles et la table des utilisateurs , Quand vous créez une table In Tableau des pointeurs d'objets pour ajouter une table utilisateur à la structure de l'article correspondant à la table d'article , Et définir plusieurs à plusieurs relations ( orm:“rel(m2m)” ), Ajouter un tableau de pointeurs d'objets pour la table d'articles dans la structure correspondante de la table d'utilisateurs , Et définir une relation inverse de plusieurs à plusieurs ( orm:“reverse(many)” ) Quand le tableau est généré , La base de données génère un tableau des relations entre l'utilisateur et l'article ,Il y a trois champs,Id,Tableau des utilisateursId,Liste des articlesID.Comme le montre la figure ci - dessous::
    GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No2Zhang.

    Opérations d'insertion multiples à multiples

o := orm.NewOrm()//1.Obtenir l'opérandearti:= Article{Id: 1}//Accèsarticle Multi - à Multi - opérandes pour m2m := o.QueryM2M(&arti, "users")// Le premier objet paramètre doit avoir une clé primaire , Le deuxième argument est le nom du champ // Obtenir l'objet à insérer user := &User{Id:1}o.Read(&user)// Insertion Multi - à Multi - objets num, err := m2m.Add(user)// Les paramètres peuvent être des objets ,Pointeur,Tableau d'objets,Tableau de pointeurs

Plusieurs à plusieurs requêtes: Il y a deux façons: Première catégorie:Utilisation directereadRequête,Et puis ajouter LoadRelated () Fonction pour associer deux tableaux .Les codes sont les suivants::

post := Post{Id: 1}err := o.Read(&post)num, err := o.LoadRelated(&post, "Tags")

L'avantage est simple,Rapide. L'inconvénient est que la valeur de retour n'est pas queryseter, Impossible d'appeler une autre requête avancée . Deuxième approche, Est une requête par filtre , Après avoir spécifié le tableau ,AvecFilter() Filtrer les conditions appropriées ,Le premier paramètre est Champs représentant un autre tableau __ Nom de l'autre table __ Champs comparés (Note double soulignement), Le deuxième champ est la valeur à comparer , Notez que cet ordre est l'inverse de l'ordre d'insertion du tableau .Les codes sont les suivants::

1.1Ajouter un type

Après analyse des opérations entre trop de tables , Nous allons mettre en œuvre des activités liées au type , Nous devons d'abord ajouter le type .

1.1.1 Ajouter un type d'affichage de page

  • Assurez - vous que le chemin de requête affiché pour le type add est /AddArticleType

  • Ajouter le code correspondant au fichier de routage .

beego.Router("/addArticleType",&controllers.ArticleController{},"get:ShowAddType")
  • Puis il est mis en œuvre dans le Contrôleur ShowAddTypeFonctions, Spécifiez d'abord simplement la vue .Les codes sont les suivants::
// Afficher la page ajouter un type d'article func(this*ArticleController)ShowAddType(){    this.TplName = "addType.html"}
  • Puis saisissez la requête dans le navigateur http://192.168.110.74:8080/addArticleType,La page s'affiche comme suit::
    GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No3Zhang.

    Comme le montre la page, Nous ajoutons l'interface type d'article ,En deux, L'un est que tous les types sont affichés sous forme de tableau ci - dessus , L'un est d'ajouter une catégorie ci - dessous . Commençons par ajouter une catégorie .

1.1.2 Ajouter un type de traitement des données

Il est plus facile d'ajouter un type d'entreprise , Le premier est de modifier le contenu de notre page de vue ,Voilà.form Méthode de demande d'étiquette et chemin de demande ,Les codes sont les suivants::

<form method="post" action="/HandleAddType">

Ensuite, nous allons modifier le fichier de routage , Assigner un contrôleur à la demande ,Préciser la méthode:

beego.Router("/addArticleType",&controllers.ArticleController{},"get:ShowAddType;post:HandleAddType")

Ensuite, nous implémentons le spooler , Cette fonction est implémentée selon les mêmes étapes que les implémentations précédentes pour ajouter des articles , Le traitement du Code est encore plus simple , Pas d'analyse détaillée ,Nous regardons directement le Code:

// Traitement ajouter des données de type article func(this*ArticleController)HandleAddType(){    //Obtenir des données    typeName := this.GetString("typeName")    //Vérification des données    if typeName == ""{        beego.Info("Impossible d'ajouter des données")        return    }    //Insérer une base de données    o := orm.NewOrm()    var articleType models.ArticleType    articleType.Tname = typeName    if _,err :=o.Insert(&articleType);err != nil{        beego.Info("Impossible d'ajouter des données")        return    }    //Retour à la vue    this.TplName = "addType.html"}

Ici, nous retournons à la vue de la bonne façon ou de la mauvaise façon ,Réfléchis un peu!

1.1.3 Type de requête données

Maintenant que nous avons les données de notre table de type , Vous pouvez remplir les données sur la page pendant qu'elle est affichée

  • Code de fond
// Afficher la page ajouter un type d'article func(this*ArticleController)ShowAddType(){    //Recherche de données    o := orm.NewOrm()    var articleTypes []models.ArticleType    o.QueryTable("ArticleType").All(&articleTypes)    // Passer les données à la vue et spécifier la vue     this.Data["articleTypes"] = articleTypes    this.TplName = "addType.html"}
  • Voir le Code Dans la page de vue , Le tableau passé par notre Contrôleur de boucle ,Obtenir les données dont nous avons besoin
{{range .articleTypes}}    <tr>       <td>{{.Id}}</td>       <td>{{.Tname}}</td>       <td><a href="javascript:;" class="edit">Supprimer</a></td>    </tr>{{end}}

À ce moment - là, nous entrons l'adresse dans le navigateur http://192.168.110.75:8080/addArticleType ,Obtenir la page suivante:

GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No5Zhang.

Ajouter un test de type , Puis il a découvert que la page n'avait toujours pas de type d'affichage , Ça veut dire qu'on a un problème avec le Code ,Où est le problème?? Rappelez - vous les questions de réflexion que vous avez laissées ? Après avoir ajouté le type d'article , C'est le rendu direct qui charge la vue , Aucune donnée n'a été transmise à la vue à ce stade , Donc il n'y a pas d'affichage de type . De tels résultats et notre entreprise Non conforme, Donc nous devons changer la façon dont nous Sautons la page après avoir ajouté le type pour rediriger , Et voir les résultats , Le type trouvé s'affiche normalement .

1.2 Page d'accueil selon les options de la boîte déroulante , Obtenir différents types de données

Il y a des données de type maintenant , Nous devons également ajouter le type ci - dessus lorsque nous ajoutons des articles .

1.2.1 Ajouter un article avec type

  • Vous devez ajouter une liaison de données de type à la boîte déroulante de type lors de la présentation de la page Obtenir des données en arrière - plan( Écrivez le Code pertinent dans la fonction afficher ajouter un article )
// Afficher l'interface ajouter un article func (this*ArticleController)ShowAddArticle(){    //Recherche de données    o := orm.NewOrm()    var articleTypes []models.ArticleType    o.QueryTable("ArticleType").All(&articleTypes)    // Passer les données à la vue et spécifier la vue     this.Data["articleTypes"] = articleTypes    this.TplName = "add.html"}

Voir les données de présentation Boucle pour obtenir des données, Afficher le nom du type dans la boîte déroulante

<select class="sel_opt" name="select">     {{range .articleTypes}}            <option>{{.Tname}}</option>     {{end}}</select>
  • Spécifier le type d'article lors de l'ajout d'un article ,Les codes sont les suivants::
// Spécifiez le type d'article pour l'objet article     var articleType models.ArticleType    articleType.Tname = typeName    o.Read(&articleType,"Tname")    article.ArticleType = &articleType    //Insérer    o.Insert(&article)

1.2.2 Lorsque la page de liste affiche l'article , Informations sur le type de présentation .

  • Consultez tous les chapitres de questions , Tableau des types d'articles associés ( Ajoutez RelatedSel(“ArticleType”)),Les codes sont les suivants::
qs.Limit(pageSize,start).RelatedSel("ArticleType").All(&articles)

Afficher lors de l'affichage

{{range .articles}}     <tr>         <td>{{.ArtiName}}</td>         <td><a href="ShowArticleDetail?id={{.Id}}">Voir les détails</a></td>         <td> {{.Atime.Format "2006-01-02-15-04-05"}}</td>         <td>{{.Acount}}</td>         <td><a href="/DeleteArticle?id={{.Id}}" class="dels">Supprimer</a></td>         <td><a href="UpdateArticle?id={{.Id}}">Édition</a></td>         <td>{{.ArticleType.Tname}}</td>     </tr>{{end}}

C'est là que vous découvrez, Aucun des articles précédemment ajoutés n'est affiché , Tu te souviens de ce que nous avons dit plus tôt sur les opérations Multi - tables ,PlusRelatedSelAprès, Si le champ correspondant n'a pas de données , Impossible de trouver .

1.2.3 Selon les options de la boîte déroulante , Obtenir différents types de données

  • Type de requête données , Et lier les données à la boîte déroulante Ce code d'entreprise est le même que celui de l'article ajouté , On ne va pas faire d'analyse détaillée. ,Regardez le Code.:
//Recherche de données    var articleTypes []models.ArticleType    o.QueryTable("ArticleType").All(&articleTypes)    this.Data["articleTypes"] = articleTypes

Voir le Code:

<select name="select" id="select" class="sel_opt">    {{range .articleTypes}}          <option selected="true">{{.Tname}}</option>    {{end}}</select>
  • Sélectionnez le type selon la boîte déroulante , Obtenir le même type d'article Transmettre les données de type sélectionnées à l'arrière - plan Nous avions l'habitude de transmettre des données avec formFormulaire,On l'utilise encore ici.form Le formulaire enveloppe la boîte déroulante , Les données sélectionnées sont ensuite transmises à l'arrière - plan .Les codes sont les suivants::
<form method="get" action="/ShowArticleList">     <select name="select" id="select" class="sel_opt">          {{range .articleTypes}}               <option selected="true">{{.Tname}}</option>          {{end}}     </select></form>

Penser,Pourquoi on utilisegetDemande de ne paspostDemande

Il n'y a pas de bouton de demande d'envoi ici ( Essayez de ne pas modifier la page de design artistique ),Nous passonsjsDemande d'envoi de code,jsLes codes sont les suivants::

$("#select").change(function () {     $("#form").submit()})

Selon le type obtenu ,Combien de données sont demandées, Et afficher le même type d'article Obtenir les données transmises par l'avant

// Obtenir le nom du type     typeName := this.GetString("select")

Par type, Combien de données sont disponibles pour la requête ,Mais, Il est important de noter qu'il s'agit d'une demande sans nom de type , Il faut donc faire un jugement ,Les codes sont les suivants::

// Obtenir le nom du type typeName := this.GetString("select")//Recherche de données, Et la pagination o := orm.NewOrm()qs := o.QueryTable("Article")var count int64//Vérification des donnéesif typeName == ""{    count,_ =qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Count()}else {    count,_ =qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Count()}

Les autres codes d'entreprise pour le traitement de la pagination restent inchangés ,Les codes sont les suivants::

// Déterminer le nombre d'affichages par page pageSize := 2//Obtenir le nombre total de pagespageCount :=math.Ceil(float64(count) / float64(pageSize))//Obtenir le numéro de pagepageIndex,err := this.GetInt("pageIndex")if err != nil{    pageIndex = 1}// Déterminer la position de départ des données start := (pageIndex - 1) * pageSize

Rechercher le même type de données par type , Il faut aussi faire un jugement. .Les codes sont les suivants::

// Interroger le type de données correspondant var articles []models.Articleif typeName ==""{    qs.RelatedSel("ArticleType").Limit(pageSize,start).All(&articles)}else {    qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Limit(pageSize,start).All(&articles)}

Les autres codes restent inchangés, Obtenir le code complet de la page de liste ci - dessous :

func(this*ArticleController)ShowArticleList(){    // Obtenir le nom du type     typeName := this.GetString("select")    //Recherche de données, Et la pagination     o := orm.NewOrm()    qs := o.QueryTable("Article")    var count int64    //Vérification des donnéess    if typeName == ""{        count,_ =qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Count()    }else {        count,_ =qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Count()    }    // Déterminer le nombre d'affichages par page     pageSize := 2    //Obtenir le nombre total de pages    pageCount :=math.Ceil(float64(count) / float64(pageSize))    //Obtenir le numéro de page    pageIndex,err := this.GetInt("pageIndex")    if err != nil{        pageIndex = 1    }    // Déterminer la position de départ des données     start := (pageIndex - 1) * pageSize    // Interroger le type de données correspondant     var articles []models.Article    if typeName ==""{        qs.RelatedSel("ArticleType").Limit(pageSize,start).All(&articles)    }else {        qs.RelatedSel("ArticleType").Filter("ArticleType__Tname",typeName).Limit(pageSize,start).All(&articles)    }    // Interrogation de certaines données de la base de données     //Obtenir des données de type    //Recherche de données    var articleTypes []models.ArticleType    o.QueryTable("ArticleType").All(&articleTypes)    this.Data["articleTypes"] = articleTypes    this.Data["count"] = count    this.Data["pageCount"] = int(pageCount)    this.Data["pageIndex"] = pageIndex    // Transmettre les données et spécifier les vues     this.Data["articles"] = articles    this.TplName = "index.html"}

C'est là que vous regardez la page. ,Il y a un problème., Une option n'a jamais pu être sélectionnée .Pourquoi??

Parce que, Chaque fois que nous changeons les options de la boîte déroulante ,Tout va bien se passer.jsEnvoyerget Demande à l'arrière - plan , L'arrière - plan interroge à nouveau toutes les boîtes déroulantes de liaison de table de type , Donc chaque fois qu'il y a une donnée ,Dans ce cas, Nous avons sélectionné les données affichées , On ne peut pas déclencher jsEnvoyer la demande,Parce quejs Pensez que l'affichage de la boîte déroulante n'a pas changé . Il y a aussi un problème avec l'affichage de la boîte déroulante ,Comment résoudre ce problème?

1.2.4 Résoudre les problèmes d'affichage des options de la boîte déroulante

​ Grâce à l'analyse précédente, Nous savons que chaque boîte déroulante récupère les données de type de la base de données pour la liaison , C'est là que nous devons ajouter un jugement au type sélectionné. , Lorsque les données extraites de la base de données sont du type sélectionné , Donne les propriétés de l'option drop - down selectedSet totrue. L'arrière - plan passe d'abord le nom de type actuellement sélectionné à la vue ,Les codes sont les suivants::

// Passe le nom de type sélectionné dans la boîte déroulante à la vue this.Data["typeName"] = typeName
  • Traitement du Code frontal Dans la vue, nous recevons le type actuellement sélectionné transmis par le Contrôleur , Comparez ensuite les noms de type dans la base de données , Si c'est le même, définissez - le. Si c'est différent, ne le définissez pas ,Les codes sont les suivants::
<select name="select" id="select" class="sel_opt">     {{range .articleTypes}}          {{if compare .Tname $.typeName}}                <option selected="true">{{.Tname}}</option>          {{else}}                <option>{{.Tname}}</option>          {{end}}     {{end}}</select>

Il est important de noter que, Si les données transmises par le Contrôleur sont obtenues en boucle ,Pas directement. . ,Oui. $.

Puis rafraîchir la page, Nous avons découvert que le problème pouvait être résolu .

2.SessionEtCookie

Ensuite, regardons de nouveau ce que notre projet n'a pas encore fait ?1. On ouvre l'interface de connexion et on découvre , L'interface de connexion a une option de nom d'utilisateur d'enregistrement , Cette fonctionnalité n'est pas encore implémentée .2. Nous mettons en œuvre des fonctionnalités qui ressemblent en fait à une classe de nouvelles APPDans les coulisses, Ce genre de page nécessite certainement un jugement de connexion , Donc nous devons encore faire un jugement d'atterrissage .3. Il y a un jugement d'atterrissage , La fonction de connexion de sortie est sur le point d'être réalisée .4. Ouvrir la page détails de l'article , Nous avons constaté qu'il n'y a pas eu d'implémentation pour parcourir cette ligne récemment , Ici aussi, nous devons réaliser .
Avant de réaliser ces quatre fonctions, l'enseignant vous présente un nouveau point de connaissance ,SessionEtCookie, Nous avons besoin de ces quatre fonctions .AlorsSessionEtCookieQu'est - ce que c'est??SessionEtCookie Il y a des moments où l'action est la même , Ils sont tous utilisés pour sauvegarder les données des utilisateurs . Mais certaines de leurs caractéristiques sont très différentes , Ce qui fait que leurs scénarios d'application sont différents . Ensuite, regardons ces deux technologies en détail .
Cookie
Pour conserver les données de l'utilisateur pendant un certain temps ,Données stockées sur le client( Le client du site est le navigateur ), Peut être réglé lorsque activé CookieDurée de validité de, Quand l'heure sera finie ,CookieÉchec.
Beego- Oui.Cookie Suppression de l'accès à
BeegoStocker les données dansCookieLe Code central est le suivant::

this.Ctx.SetCookie(key,value,time)//Le premier paramètre estCookieDekeyValeur,Le deuxième paramètre estCookieDevalueValeur, Le troisième paramètre est défini CookieDurée de validité de.

Prends - le.CookieLe Code pour:

this.Ctx.GetCookie(key)//Le paramètre estCookieDekeyValeur, La valeur de retour correspond à valueValeur. Quand il n'y a pas de correspondance CookieOuCookieÉchec,Renvoie une chaîne vide

SupprimerCookieLe Code pour:

this.Ctx.SetCookie(key,value,0)//Le premier paramètre estCookieDekeyValeur, Deuxième paramètre n'importe quelle valeur , Le troisième paramètre met Cookie La valeur de est définie à moins de 0, Ça ne marchera pas tout de suite .

Session
Il est également utilisé pour sauvegarder les données de l'utilisateur pendant un certain temps , Mais les données sont stockées sur le serveur ,BeegoActiverSesssion Doit être activé dans le fichier de configuration SessionFonction.InBeegoEn service,Pas de réglage généralSessionLe temps,Quand le navigateur est fermé,SessionÉchec.
**Beego- Oui.SessionAccès à **
Si vous souhaitez utiliser SessionFonction, Vous devez d'abord définir dans le profil Sessionon=true
BeegoStockageSessionCode:

this.SetSession(key,value)//Deux paramètres,L'un estSessionDekey,Le deuxième estSessionDeValue

AccèsSessionLe Code pour:

this.GetSession(key)//Le paramètre estSessionDekeyValeur,La valeur de retour estSessionCorrespondantvalueValeur,Le type estinterface{}

SupprimerSessionLe Code pour:

this.DelSession(key)//Le paramètre estSessionDekeyValeur

Nous utilisons des tableaux pour analyser leurs différences

C'est différent. Cookie Session
Emplacement du stockage des données Client Serveur
Sécurité des données(En comparaison) Faible Élevé
Cycle de vie Avec la fin du temps de réglage ,Fin du cycle de vie Quand le navigateur est fermé,Fin du cycle de vie
Scénarios applicables Faible exigence de sécurité , Besoin de stocker des données plus longues Exigences de sécurité , Données qui ne nécessitent pas de stockage à long terme

Après avoir brièvement compris ces deux points de connaissance ,Voyons voir, Comment réaliser les quatre fonctions restantes de notre projet .

2.1Rappelez - vous le nom d'utilisateur

Sur la page d'atterrissage, si nous cochons la case pour nous souvenir du nom d'utilisateur , La prochaine fois que j'atterrirai , La colonne nom d'utilisateur affiche par défaut le dernier nom d'utilisateur stocké . Et rappelez - vous que le nom d'utilisateur est vérifié par défaut , Si nous décochons Mémoriser le nom d'utilisateur , Ne pas afficher le nom d'utilisateur la prochaine fois que vous accédez à la page de connexion , Rappelez - vous que le nom d'utilisateur n'est pas vérifié par défaut .En général, Rappelez - vous votre nom d'utilisateur pendant longtemps , Les exigences en matière de facteur de sécurité ne sont pas non plus très élevées ,Ici, on utiliseCookiePour réaliser cette fonction.
On a regardé le Code de vue et on a trouvé , Quand j'ai atterri ,form Le formulaire présente les données de la case à cocher Mémoriser le nom d'utilisateur ,Avecbeego.Info() Imprimer les données obtenues , Découvrez que lorsque le nom d'utilisateur est sélectionné, nous obtenons une chaîne en arrière - plan "on", Impossible d'obtenir sans sélection , Selon ce phénomène, , On peut juger si dunley , Quand j'ai atterri ,Nous pouvons utiliserCookieNom de l'utilisateur de stockage, Supprimer sans sélectionner Cookie.Les codes sont les suivants::

// Traitement des données du nom d'utilisateur enregistré //Obtenir des donnéesremember := this.GetString("remember")beego.Info(remember)if remember == "on"{    beego.Info(remember)    this.Ctx.SetCookie("userName",userName,1000)}else {    this.Ctx.SetCookie("userName",userName,-1)}

Lors de la présentation de la page d'atterrissage ,Nous devons obtenirCookieValeur de,Et juger,Si vous obtenezCookieValeur de, Afficher dans le nom d'utilisateur , Et réglez le nom d'utilisateur mémorisé à l'état sélectionné ,Si vous n'obtenez pasCookie La valeur de définit le nom d'utilisateur à NULL , Rappelez - vous que le nom d'utilisateur n'est pas sélectionné ,Les codes sont les suivants::

//Obtenir des donnéesuserName := this.Ctx.GetCookie("userName")//Juger les données, Ensuite, définissez les données à transmettre à la vue if userName != ""{    this.Data["userName"] = userName    this.Data["checked"] = "checked"}else{    this.Data["userName"] = ""    this.Data["checked"] = ""}

Réception des données en vue :

<form  class="login_form"  name = "login" action="/login" method="post">    <h1 class="login_title">Connexion utilisateur</h1>    <input type="text"  class="input_txt" name = "userName" value="{{.userName}}">    <input type="password" name = "passwd"  class="input_txt">    <div class="remember"><input type="checkbox" name="remember" {{.checked}} ><label>Rappelez - vous le nom d'utilisateur</label></div>    <input type="submit" value="Den Enregistrement" class="input_sub"></form>

Attention!,QuandcheckboxAjouter uncheckedPropriété,checkbox C'est l'état sélectionné

2.2Jugement de débarquement

Parce que tout ce que nous faisons est l'interface de gestion de fond , Donc nous devons faire un jugement d'atterrissage . On utilise SessionPour réaliser cette fonction.
En serviceSession N'oubliez pas de définir sessionon=true
Après une connexion réussie, définissez Session,Les codes sont les suivants::

//Paramètressessionthis.SetSession("userName",userName)

Les fonctions de plusieurs pages d'affichage en arrière - plan doivent obtenir session,Et juger,Les codes sont les suivants::

//Accèssession,Et déterminer si elle est vide, Si vous sautez à la page de connexion vide userName := this.GetSession("userName")if userName == nil{    this.Redirect("/ShowLogin",302)    return}

2.3Déconnecter

Quitter le login, c'est supprimer le login session, Puis retournez à l'interface de connexion .

  • Il y a un login de sortie sur la page de liste des articles , On doit lui en ajouter un. href, .Ici, nous spécifions le chemin de demande pour quitter le login comme /logout
<a href="/logout" class="logout fr">Reculez! Sortez!</a>
  • Ensuite, nous spécifions le Contrôleur et la méthode pour la requête dans le routage
beego.Router("/logout",&controllers.ArticleController{},"get:Logout")
  • Et ensuite nous réalisons unLogoutFonctions,La logique d'entreprise est simple,Nous regardons directement le Code
//Déconnecterfunc(this*ArticleController)Logout(){    //Supprimersession    this.DelSession("userName")    //Saut    this.Redirect("/login",302)}

2.4Vues récentes

La navigation la plus récente consiste à ajouter des informations utilisateur à un article lorsque nous le parcourons , Et après avoir demandé ces informations ,Afficher sur la page.

  • Ajouter des informations de navigation Nous sommes ici pour ajouter des informations d'utilisateur pour la navigation au tableau des articles .Les codes sont les suivants::
//AccèsORMObjeto := orm.NewOrm()// Obtenir l'objet auquel les données sont insérées var article models.Articlearticle.Id = ido.Read(&article)// Obtenir plusieurs à plusieurs opérandes , Avec une fonction QueryM2M(), Le premier paramètre est l'objet à insérer les données , Le deuxième paramètre est le nom du champ à insérer , La valeur de retour est de plusieurs à plusieurs opérandes m2m := o.QueryM2M(&article,"Users")// Obtenir l'objet à insérer user := models.User{Name:userName.(string)}o.Read(&user,"Name")// Plusieurs à plusieurs Inserts m2m.Add(user)
  • Afficher les informations de navigation Il existe deux façons d'afficher plusieurs à plusieurs informations Première catégorie, Chargement direct de plusieurs à plusieurs relations , La fonction utilisée est LoadRelated(), Le premier paramètre est l'objet de requête , Le deuxième paramètre est le champ Multi - à Multi - relationnel ,Les codes sont les suivants::
num,err := o.LoadRelated(&article,"Users")

À ce moment - là, nous pouvons faire défiler les informations des utilisateurs les plus récents à l'avant , Ici, nous utilisons la deuxième syntaxe de boucle de vue :

<label>Vues récentes:</label><p class="detail">{{range .article.Users}}{{.Name}} | {{end}}</p>

À ce moment - là, nous regardons les détails plusieurs fois et nous trouvons un problème , Lorsque nous ajoutons une relation, nous la parcourons et l'ajoutons une fois , Ensuite, Nous afficherons à plusieurs reprises le nom d'utilisateur du même utilisateur ,Les effets sont les suivants:

GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No6Zhang.

Mais d'habitude, quand on navigue sur le Web , Un utilisateur a navigué pour afficher les informations de l'utilisateur une seule fois , Il faut donc qu'on y aille , Vous vous souvenez de la méthode de suppression des requêtes avancées que nous avons décrite précédemment ? Distinct() Poids mort, Mais cette fonction doit être queryseterObjet à utiliser, .Donc notre première méthode de requête Multi - à - multi ne fonctionne pas . Ici, nous utilisons le deuxième type de requête Multi - à Multi .Les codes sont les suivants::

var users []models.Usero.QueryTable("User").Filter("Articles__Article__Id",article.Id).Distinct().All(&users)

Attention!: Ce que nous insérons ici, c'est que articleInséreruser, Mais la requête vient de userObtenir.

3.Optimisation des projets

3.1Filtre de routage

Quand le projet sera réalisé , Seuls les jugements de connexion ont été ajoutés à la page liste des articles et à la page détails ,Réfléchissons un peu, Notre cas est en fait tout l'arrière - plan , Donc chaque page doit ajouter un jugement de connexion , Alors nous avons besoin d'ajouter des jugements de connexion à chaque endroit ,Beaucoup de code répété. Voici une nouvelle technologie ,Filtre de routage, Ajouter un filtre au niveau du routage , Réaliser le jugement de connexion . Voyons ce qu'est un filtre de routage .
Action: Selon les règles de correspondance spécifiées In Phase opérationnelle spécifique du projet Vas - y. Exécuter une fonction personnalisée ,Les fonctions sont généralement placées dansbeego.router()Avant .
Alors regardons le format de la fonction de filtre de routage :

beego.InsertFilter(pattern string, position int, filter FilterFunc)

Le premier paramètre est la règle de correspondance de routage ,Prise en charge de la régularisation
Le deuxième paramètre est de spécifier la phase d'exécution du projet ,Inbeego Pendant l'exécution du projet , Le cadre nous a aidés en cinq étapes ,Respectivement.:
a) BeforeStatic Avant l'adresse statique
b) BeforeRouter Avant de chercher le chemin
c) BeforeExec Après avoir trouvé la route , Commencer l'exécution correspondante Controller Avant
d) AfterExec Fin de la mise en œuvre Controller Filtres exécutés après logique
e) FinishRouter Filtres exécutés après l'exécution de la logique
Les correspondances spécifiques sont les points de temps du graphique ci - dessous :

GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No7Zhang.

Troisième paramètre, Est de spécifier une fonction de filtre .

Les filtres de routage sont généralement placés dans beego.Router()Avant.

Alors regardons le format de la fonction filtre :

type FilterFunc func(*context.Context)

Le paramètre doit êtrecontext.Context

Exemple de code:

var BeforeExecFunc = func(ctx * context.Context) {    userName:=ctx.Input.Session("userName")    if userName == nil{        ctx.Redirect(302,"/login")    }}beego.InsertFilter("/index",beego.BeforeExec,BeforeExecFunc)

3.2Afficher la disposition

Après avoir implémenté la fonction filtre , Revenons à notre projet. ,La page s'affiche comme suit::

GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No8Zhang.

Vous trouverez quelque chose sur chaque page , Peut - on éviter ces répétitions ? Voici un nouveau point de connaissance ,Afficher la disposition:
**Action:** En configurant la page modèle , D'autres pages peuvent appeler directement le modèle , Évitez de traiter à nouveau les codes en double .
La disposition de la vue est essentiellement deux html L'épissage de l'interface , Par exemple, nous avons maintenant un htmlInterfacelayout.html, Il y a aussi une interface qui ne contient que l'ajout d'articles Business , Nous pouvons assembler deux pages en fonction de .
Les opérations sont les suivantes:
Le Code du Contrôleur est le suivant::

this.Layout = "layout.html"this.TplName = "add.html"

layout.htmlCode dans:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Page d'administration de fond</title>    <link rel="stylesheet" type="text/css" href="/static/css/reset.css">    <link rel="stylesheet" type="text/css" href="/static/css/main.css">    <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script></head><body><div class="header">    <a href="#" class="logo fl"><img src="/static/img/logo.png" alt="logo"></a>    <a href="/logout" class="logout fr">Reculez! Sortez!</a></div><div class="side_bar">    <div class="user_info">        <img src="/static/img/person.png" alt="Zhang Dashan">        <p>Bienvenue. <em>Li Lei</em></p>    </div>    <div class="menu_con">        <div class="first_menu active"><a href="javascript:;" class="icon02">Gestion des articles</a></div>        <ul class="sub_menu show">            <li><a href="#" class="icon031">Liste des articles</a></li>            <li><a href="/addArticle" class="icon032">Ajouter un article</a></li>            <li><a href="#" class="icon034">Ajouter une catégorie</a></li>        </ul>    </div></div>{{.LayoutContent}}</body></html>

Attention à l'intérieur. {{.LayoutContent}}, Cette étiquette est utilisée pour stocker add.htmlOù?.

add.html Pour supprimer le même code ,Les codes sont les suivants::

    <div class="main_body" id="main_body">        <div class="breadcrub">            Position actuelle:Gestion des articles>Ajouter un article        </div>        <div class="pannel">            <form method="post" action="/addArticle" enctype="multipart/form-data">            <h3 class="review_title">Ajouter un article</h3>            <div class="form_group">                <label>Titre de l'article:</label>                <input type="text" class="input_txt2" name="articleName" >            </div>            <div class="form_group">                <label>Type d'article:</label>                <select class="sel_opt" name="select">                    {{range .articleTypes}}                        <option>{{.Tname}}</option>                    {{end}}                </select>            </div>            <div class="form_group">                <label>Contenu de l'article:</label>                <textarea class="input_multxt" name="content"></textarea>            </div>            <div class="form_group">                <label>Télécharger l'image:</label>                <input type="file" class="input_file"  name="uploadname">            </div>            <div class="form_group indent_group line_top">                <input type="submit" value="Tim. Plus" class="confirm">                <span>{{.errmsg}}</span>            </div>        </form>        </div></div>

Saisissez l'URL dans le navigateur, À ce moment - là, vous pourriez trouver le problème , Nos étiquettes Cette petite partie ne peut pas être changée. .Ici, on peut passer parthis.DataVoilà.layoutTransmission de la valeur.

  • jsTransfert de code Les étudiants attentifs découvriront , Nous avons besoin d'ajouter jsCode,C'est Comment le contenu est - il transmis à la page , Voici une autre fonction LayoutSection. **LayoutSection **Action:this.LayoutFichier modèle spécifié, Peut réaliser l'épissage de deux pages , C'est parfois jsOucssStyles, Comment passer ?Nous pouvons utiliserLayoutSectionPasser. **LayoutSection **:Utilisation: Code du Contrôleur:
this.Layout = " layout.html"this.LayoutSections = make(map[string]string)this.LayoutSections["Scripts"] = "scripts.html"

Inlayout.html Ajouter ce qui suit :

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Page d'administration de fond</title>    <link rel="stylesheet" type="text/css" href="/static/css/reset.css">    <link rel="stylesheet" type="text/css" href="/static/css/main.css">    <script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script></head><body><div class="header">    <a href="#" class="logo fl"><img src="/static/img/logo.png" alt="logo"></a>    <a href="/logout" class="logout fr">Reculez! Sortez!</a></div><div class="side_bar">    <div class="user_info">        <img src="/static/img/person.png" alt="Zhang Dashan">        <p>Bienvenue. <em>Li Lei</em></p>    </div>    <div class="menu_con">        <div class="first_menu active"><a href="javascript:;" class="icon02">Gestion des articles</a></div>        <ul class="sub_menu show">            <li><a href="#" class="icon031">Liste des articles</a></li>            <li><a href="/addArticle" class="icon032">Ajouter un article</a></li>            <li><a href="#" class="icon034">Ajouter une catégorie</a></li>        </ul>    </div></div>{{.LayoutContent}}</body></html>{{.Scripts}}

3.3Supplément

Regardons en arrière, Voyez si notre projet n'a pas encore été réalisé. ? La suppression de type n'est pas encore implémentée , Certains étudiants pourraient dire , Professeur cette suppression est la même que celle de l'article , Ça ne va pas tarder. ! Voici un rappel spécial du professeur :** Les types sont liés aux opérations Multi - tables , L'effet de suppression n'est pas le même que l'article d'une seule table **
Alors regardons le type de suppression :
Encore une fois, quatre étapes :**Demande->Routage->Controller->Voir **

  • Demande Supprimer le type est implémenté dans la page ajouter le type , Il y a une étiquette supprimée sur cette page ,Comme le montre la figure ci - dessous:
    GO Développement de la langue tous les jours frais projet jour 3  CAS- Système de communiqués de presse II  - No4Zhang.

    Alors nous ajoutons un chemin de requête à cette étiquette ,La même chose., Nous devons ajouter un type au chemin de demande Id.Les codes sont les suivants::

<a href="/deleteType?id={{.Id}}" class="edit">Supprimer</a>
  • Routage Ajouter le routage approprié, Spécifiez le Contrôleur et la méthode
beego.Router("/deleteType",&controllers.ArticleController{},"get:DeleteType")
  • Controller Avec le nom de la méthode , Juste pour implémenter le Code associé :
//Supprimer le typefunc(this*ArticleController)DeleteType(){    //Obtenir des données    id,err:=this.GetInt("id")    //Données de contrôle    if err != nil{        beego.Info(err)        return    }    //Traitement des données    var articleType models.ArticleType    articleType.Id = id    o := orm.NewOrm()    o.Delete(&articleType)    //Retour à la vue    this.Redirect("/addArticleType",302)}
  • Voir Après suppression, Retour à la page de recherche , Le type a été supprimé .Mais il est important de noter, Notre type est lié à des articles connexes , Nous revenons à la page de la liste des articles ,Découverte, Supprimer le type, Supprimer également les articles liés à ce type ,C'est parce que,beego La suppression en cascade est effectuée par défaut , Puis - je définir cette suppression en cascade ?Inbeego Paramètres pour la suppression des associations intermédiaires , Est le réglage ajouté lors de la construction de la table comme suit : Définir la correspondance rel Lorsque la relation est supprimée , Comment gérer les champs relationnels .
cascade        Suppression en cascade(Par défaut)set_null       Set to NULL,Paramètres requis null = trueset_default    Définir par défaut,Paramètres requis default Valeurdo_nothing     Ne fais rien.,Ignorer

Exemple:

//Structure de l'articletype Article struct {    Id int `orm:"pk;auto"`    ArtiName string `orm:"size(20)"`    Atime time.Time `orm:"auto_now"`    Acount int `orm:"default(0);null"`    Acontent string `orm:"size(500)"`    Aimg string  `orm:"size(100)"`    ArticleType*ArticleType `orm:"rel(fk);null;on_delete(set_null)"`    Users []*User `orm:"reverse(many)"`}

4.BeegoRésumé

err:=this.GetInt(“id”)
//Données de contrôle
if err != nil{
beego.Info(err)
return
}
//Traitement des données
var articleType models.ArticleType
articleType.Id = id
o := orm.NewOrm()
o.Delete(&articleType)
//Retour à la vue
this.Redirect(“/addArticleType”,302)
}

+  Après la suppression de la vue , Retour à la page de recherche , Le type a été supprimé .Mais il est important de noter, Notre type est lié à des articles connexes , Nous revenons à la page de la liste des articles ,Découverte,**Supprimer le type, Supprimer également les articles liés à ce type **,C'est parce que,beego La suppression en cascade est effectuée par défaut , Puis - je définir cette suppression en cascade ?Inbeego Paramètres pour la suppression des associations intermédiaires , Est le réglage ajouté lors de la construction de la table comme suit :Définir la correspondance rel  Lorsque la relation est supprimée , Comment gérer les champs relationnels . 

Définir les propriétés en cascade
cascade Suppression en cascade(Par défaut)
set_null Set to NULL,Paramètres requis null = true
set_default Définir par défaut,Paramètres requis default Valeur
do_nothing Ne fais rien.,Ignorer

 Exemple:```go//Structure de l'articletype Article struct {    Id int `orm:"pk;auto"`    ArtiName string `orm:"size(20)"`    Atime time.Time `orm:"auto_now"`    Acount int `orm:"default(0);null"`    Acontent string `orm:"size(500)"`    Aimg string  `orm:"size(100)"`    ArticleType*ArticleType `orm:"rel(fk);null;on_delete(set_null)"`    Users []*User `orm:"reverse(many)"`}

4.BeegoRésumé

Résumé général, On fait ça en classe , Vous pouvez également résumer par vous - même
Auteur: Bibliothèque de modèles de bureau Grenouille

Programmation de jeux ️,Un favori pour le développement de jeux~

Si l'image n'est pas affichée depuis longtemps,Veuillez utiliserChromeNavigateur du noyau.

版权声明
本文为[Programmation de jeux]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204232027530795.html