\chapter{Prototyp}
\label{ch:prototyp}
Um die Forschungsfrage zu prüfen, wird in dieser Arbeit die Methode des Prototypings genutzt. Der Prototyp dient zum experimentellen Arbeiten und sichert eine strukturell fundierte Umsetzung des darauf folgenden Endprodukts. Der Fokus liegt dabei zunächst auf der Funktionalität der Anwendung. Prototyping wird als bevorzugte Methode gewählt um schnell ein Ergebnis zu erzielen (vgl. [Abr16]). Zudem soll aufbauend auf diesem ein Produkt realisiert werden, das als Erweiterung in das Netzwerk der Hochschule integriert werden soll.

\section{Forschungsdesign}
Das Kapitel zeigt eine kurze Übersicht der Vorgehensweise und den Leitfaden an den sich die Implementierung des Prototyps anlehnt (vgl. Abbildung 3.1.). 
Zu Beginn der Arbeit wird das sich aus der Forschungsfrage ergebenden Problem analysiert und es werden alle wichtigen Anforderungen erfasst. Dies bildet die Basis für alle weitern notwendigen Schritte um am Ende eine sinnvolle Lösung bereitstellen zu können. Die Recherche dient der Sammlung aller notwendigen Werkzeuge und gibt einen Überblick über verschiedene Hilfsbibliotheken. Das Implementieren der Applikation kann nun auf Basis der Recherche durchgeführt werden. Dazu gehört das Testen verschiedener Bibliotheken und Erweiterungen um die bestmögliche Ergebnis zu eruieren. Abschlie"send wird die Funktionalität des Prototypen getestet und evaluiert ob die Forschungsfrage ausreichend beantwortet wird. Handlungsempfehlungen und mögliche Funktionen zum Erweitern finalisieren die Arbeit.

\begin{figure}[!h]
\centering
\includegraphics[width=0.8\textwidth]{figures/forschungsdesign}
\caption{Forschungsdesign}
\hfill
\end{figure} 

\section{Organisation}

Um einen Einblick in den Aufbau eines Django-Projektes zu erlangen wird dies im folgenden genauer beschrieben. Die unterste Projektebene wird durch  \texttt{manage.py} gebildet. Sie wird unter Anderem genutzt um den lokalen Server starten zu können. In der Ebene darüber findet sich im Ordner \texttt{mysite} die Datei \texttt{settings.py}. Hier werden die allgemeinen Einstellungen der Website vorgenommen, wie zum Beispiel das Integrieren der Erweiterungen und der Pfad zu den hinterlegten Templates. Au"serdem ist die \texttt{urls.py} dort zu finden, deren Funktion bereits im Kapitel Django erläutert wurde. Im Ordner \texttt{thisisenv} sind alle Bibliotheken und Add-on's der virtuellen Umgebung hinterlegt. Der relevanteste Teil dieser Arbeit liegt im Ordner \texttt{application}. Hier sind die Datenbank-Migrationen, die Static-Files wie bootstrap und css, und alle Templates abgelegt. Zudem befindet sich hier die Logik des Prototypen, auf die im Kapitel \texttt{Funktionen} weiter eingegangen wird.


\subsection{Datenmodellierung}
Die Struktur der bereits bestehenden Datenbank im Django-Framework und die Erweiterungen dessen werden genauer erläutert. Zunächst wird auf die Ergänzung des bestehenden \texttt{UserModel} eingegangen, nachdem veranschaulicht der Abschnitt das \texttt{PostModel} und abschlie"send werden die Zusammenhänge dieser dargestellt.

\begin{figure}[!h]
\centering
\includegraphics[width=0.9\textwidth]{figures/datamodel}
\caption{Datenmodellierung von \texttt{User} und \texttt{Post}}
\hfill
\end{figure} 

Alle Modelle werden als Django-Modelle deklariert um beim Kompilieren des Codes dem Compiler mitzuteilen, dass eine Integration stattfinden muss (vgl. [Dja18a]). Mit der folgenden Eingabe
\\
\begin{addmargin}[0pt]{0pt} 
\noindent\hspace*{10mm}%
\texttt{ \$ python3 manage.py makemigrations}
\\
\end{addmargin}
werden die neun Tabellen der Modelle erstellt. Zur letztendlichen Migration wird
\\
\begin{addmargin}[0pt]{0pt} 
\noindent\hspace*{10mm}%
\texttt{ \$ python3 manage.py migrate}
\\
\end{addmargin}
ausgeführt.\\ 


\textbf{UserModel:}
\begin{addmargin}[25pt]{0pt} 
Hierbei ist das Authentifizierungssystem von Django mit einem \texttt{UserModel} bereits angelegt. Dies muss für den Prototyp um das Feld \texttt{tags} erweitert werden, sodass ein Benutzer folgende Felder aufweist (vgl. [Fou18a]):
\begin{itemize}
\item username, fist\_name, last\_name, email, groups, user\_permissions, is\_staff, is\_active, is\_superuser, last\_login, date\_joined, tags
\end{itemize}

In models.py ist der \texttt{CustomUser} dafür verantwortlich das neue Feld mit dem \texttt{Default-User} zu verknüpfen. Durch das \texttt{OneToOneField} (siehe Abbildung 3.2.) wird die Verbindung zum schon bestehenden Modell hergestellt. \texttt{OneToOne} bildet eine einzigartige Zuordnung von zwei Objekten, sodass der Rückgabewert eindeutig ist. Das hei"st, dass hier keine Rekursiven, also auf sich selbst verlinkende oder \texttt{lazy} Beziehungen möglich sind um Konflikte bei der Authentifizierung zu vermeiden. Dies ist die übliche Vorgehensweise um mit einem Primärschlüssel das Default-Model zu erweitern (vgl. [Fou18a]). \\

\begin{figure}[!h]
\centering
\includegraphics[width=1\textwidth]{figures/custommodelcode}
\caption{CustomUserModel in models.py}
\hfill
\end{figure} 


\end{addmargin}

\textbf{PostModel:}
\begin{addmargin}[25pt]{0pt} 
Das \texttt{PostModel} beschreibt alle Felder die ein Artikel enthalten kann. Basierend auf der Blog-Lösung von Djangogirls.com (vgl. [Dja18b])gehören dazu folgende:
\begin{itemize}
\item author, title, text, created\_date, published\_date, tags
\end{itemize}
Der Autor ist durch einen \texttt{ForeignKey} mit dem \texttt{UserModel} verbunden. Diese \texttt{ManyToOne} Verbindung reicht hier aus um einem Post einem Autor, also dem eingeloggten User, zuzuweisen. \texttt{Title} ist ein \texttt{CharField} und wird mit einer Zeichenbegrenzung festgelegt. Der Text hingegen kann eine beliebige Menge an Zeichen enthalten und wir deshalb als \texttt{TextField} deklariert. Erstellungsdatum und Publikation sind beides \texttt{DateTimeFields}. Ersteres muss vom Ersteller angegeben werden, Zweiteres kann zunächst durch die Zusatzangabe \texttt{null=True} offen gelassen werden. Ein weiteres Feld wird hinzugefügt um Artikeln unabhängig von Usern Tags zuordnen zu können.
\\
\end{addmargin}


\textbf{Gesamtmodellierung:}

\begin{addmargin}[25pt]{0pt} 
Die Abbildung 3.3. zeigt die Modellierung der Tabelle \texttt{User} und  \texttt{Post}. Au"serdem verdeutlicht es die Erweiterung des User-Modells von Django mit dem in der Applikation angelegtem CustomUser. Die im User vorkommenden \textit{booleschen Felder} werden im Kapitel Berechtigungen der User genauer erörtert.
\end{addmargin}


\subsection{Berechtigungen der User}
Im Allgemeinen verwendet man Berechtigungen um Benutzern Zugang zu bestimmten Resourcen in einem Netzwerk einzuräumen. Au"serdem bestimmt es die Art des Zugangs, also ob der User die Resourcen nur lesen, verändern oder löschen darf (vgl. [Com18]). Die Rechte werden meist einzelnen Individuen oder einer Gruppe zugeordnet.

Das gestaffelte Berechtigungsmanagement ist im Prototyp notwendig um den Umgang mit Informationen so sicher wie möglich zu gestalten und um die Nachhaltigkeit dieser zu bewahren. Des Weiteren soll der Prototyp als Vorlage für die Erweiterung der Hochschulwebsite dienen und daher ist eine ähnliche Verteilung der Zugangsberechtigungen sinnvoll. 

Studenten sollen zunächst Informationen weder einpflegen, noch editieren dürfen. Die einzigen Änderungen die sie vornehmen können sind auf Ihre eigene Datenbank fokussiert. Das Hinzufügen von Tags und die Sichtbarkeit damit verbundener Beiträge auf dem persönlichen Dashboard kann so gewährleistet werden. Dies soll verhindern, dass Informationen nicht zu leichtfertig geändert oder gelöscht werden. 

Dozenten und Angestellte der Hochschule sind dazu berechtigt, Posts zu erstellen, zu editieren und wieder zu löschen. Zudem können sie, wie Studenten, Tags abonnieren und das persönliche Dashboard gestalten. Das Einloggen in die Administratoroberfläche kann vorgenommen werden, jedoch sind der Gruppe noch keinerlei Rechte zugewiesen. Möchte man dies ändern, kann man das von Django bereitgestellte Feld \texttt{User Permissions} im Admin-Backend unter Users, und dem Namen der Person, die gewünschte Berechtigung zuteilen. Diese sind von Django vorgegeben und betreffen alle vorhandenen Modelle der Applikation.
Durch das Setzen des booleschen Wert \texttt{is\_staff} auf \texttt{True} beim Erstellen der Benutzer, ist es möglich im Code der Applikation Abfragen durchzuführen. Dadurch lassen sich bestimmte Views an die eingeloggte Personengruppe anpassen. So ist unter Anderem das Menü der Dozenten und Angestellten etwas umfangreicherer als jenes, der Studierenden.


\section{Funktionen}
Um die wichtigsten Funktionen des Prototypen festlegen zu können werden User Stories erstellt (vgl. Abbildung 3.4.). Diese bestehen aus kurzen Sätzen und beschreiben aus Sicht des Nutzers das Verwenden einer Funktion. Die Priorisierung bezieht sich hierbei auf die Relevanz der Funktion, wobei die Funktionen mit einem rotem Punkt sehr wichtig für den Prototypen sind, Orang wichtige Funktionen sind aber nicht unbedingt notwendig und Grün kaum Relevanz haben. \\

\begin{figure}[!h]
\centering
\includegraphics[width=0.9\textwidth]{figures/userstories}
\caption{User Stories}
\hfill
\end{figure} 

\subsection{Verwaltung der Funktionen}
Das Verwalten der Artikel soll von berechtigten Nutzern im Frontend stattfinden, während die prozessuale Logik im Code-Backend realisiert ist. Der Vorgang des Erstellens, des Löschens und des Editierens der einzelnen Einträge wird im Folgenden konkretisiert.
\\
\\
\textbf{Einen neuen Artikel erstellen: }

Das \texttt{+} in der Menüleiste leitet den Benutzer zu einer Unterseite. Hier können alle Felder befüllt werden, die im \texttt{PostForm}-Formular in der Datei \texttt{forms.py} festgelegt wurden. Dazu gehören der Titel und der Text, die als Pflichtfelder gelten. Das Feld \texttt{Tags} muss ebenfalls mindestens einen Wert enthalten um die Validierung der Eingaben sichern zu können. Eine Ausnahme bildet das Datum der Veröffentlichung. Bleibt das Feld leer so wird der Beitrag automatisch der Liste der Entwürfe beigefügt. 

Speichert der Benutzer den Artikel, so werden im Backend die Daten wie folgt verarbeitet. In der View \texttt{post\_new} wird zunächst die Validität aller Eingaben geprüft. Falls dies der Fall ist, wird der jeweilige Beitrag als Objekt zurückgegeben, jedoch durch das optionale Keywort \texttt{commit=false} noch nicht in der Datenbank gespeichert. Das ist notwendig um dem Objekt spezifische Informationen mitzugeben. In diesem Kontext wird der aktuell eingeloggte User als Autor hinterlegt. Jedoch birgt die Vorgehensweise eine Problematik im Speichervorgang einer \texttt{ManyToMany} Relation zwischen zwei Modellen. Da Informationen nur auf ein bereits in der Datenbank bestehendes Objekt gesichert werden können ist dies zunächst nicht möglich (vgl. [Fou18b]).
Im Prototyp nutzt das \texttt{PostModel} die \texttt{ManyToMany} Konnektivität mit dem Modell des \texttt{TaggabelManagers}. Um die Eingabe des Tag-Felds trotzdem im neuen Artikel speichern zu können, wird zunächst das Objekt gespeichert, um nachdem explizit das von Django zur Verfügung gestellte \texttt{form.save\_m2m()} aufrufen zu können. Dieser Befehl zwingt die Daten der \texttt{ManyToMany} Relation zu speichern.

Die eindeutige Zuordnung der Eingabe im Front-end zur Verarbeitung der Artikel im Back-end ist mit einem \texttt{Primary Key} realisiert. Das \texttt{PostModel} bekommt beim Anlegen keinen Schlüssel zu einem Feld zugewiesen. Django erstellt automatisiert beim Speichern der Tabelle diesen als \texttt{AutoField} im Feld \texttt{Id} und identifiziert dies automatisch bei jedem neu Erstellen eines Objekts. Somit sind alle Objekte eindeutig zuordenbar und können mit dem Kommando \texttt{post.pk} jederzeit abgefragt werden.
\\
\\
\textbf{Einen bereits vorhandenen Artikel löschen: }

In der Detailansicht eines Artikels ist es möglich diesen zu entfernen. Die View \texttt{post\_remove} selektiert über den im Template mitgegebenen \texttt{Primary Key} das Objekt und speichert dies in der Variable \texttt{post}. Dieser wird gelöscht mit dem Befehl \texttt{post.remove()} und eine Umleitung am Ende der View-Definition schickt den Benutzer auf die Seite der Artikelliste. Hier wird, eine zuvor in der View generierte Nachricht, visualisiert, sodass der Benutzer sicher sein kann, dass der Vorgang abgeschlossen ist.
\\
\\
\textbf{Einen bereits vorhandenen Artikel bearbeiten: }

Ähnlich wie beim Löschen eines Artikel, kann man diesen in der Detailansicht bearbeiten. Dazu wird in der View über den \texttt{Primary Key} der Artikel einer Variable \texttt{post} zugeordnet. Die bedingte Anweisung rendert zunächst die \texttt{PostForm}, mit dem bereits eingepflegten Inhalt durch eine GET-Abfrage (vgl. Abbildung 3.5.). 

\begin{figure}[!h]
\centering
\includegraphics[width=0.9\textwidth]{figures/postedit}
\caption{Prototyp Artikel-Editor.}
\hfill
\end{figure} 

Veranlasst der Benutzer die Speicherung des Artikels im Front-end, wird die bedingte Abfrage der Abbildung 3.6. in Zeile 91 erfüllt. Die POST-Abfrage ist hier notwendig, da Django nur so Daten in der Datenbank verändert. Eine Begründung hierfür ist die Art der Übertragung der Daten an den Server. \texttt{POST-Requests} bündeln alle Daten, verschlüsseln diese und senden sie dann an der Server (vgl. [Fou18c]). Dadurch ist der Vorgang einfacher kontrollierbar und mit einem \texttt{csrf-Token} im Template ebenfalls gegen Cross-Site-Request-Fälschung abgesichert. Die weitere Vorgehensweise der Funktion ist identisch zum bereits erwähnten neu Erstellen eines Artikels und muss nicht weiter beschrieben werden.\\

\begin{figure}[!h]
\centering
\includegraphics[width=0.9\textwidth]{figures/post-edit-view}
\caption{Funktion post\_edit, Auszug aus views.py.}
\hfill
\end{figure} 

\subsection{Artikel abonnieren}

Das Abonnieren bestimmter Themengebiete ist eines der wichtigsten Funktionen im Prototyp um die eingepflegten Informationen zielgerichtet anzeigen zu können.

Unter Berücksichtigung aller Vor- und Nachteile wird ein Tag-Modell zur Umsetzung  gewählt. Wie bereits in der Datenmodellierung angedeutet (vgl. Datenmodellierung), besitzt jeder Artikel beschreibende Tags. Hierbei handelt es sich um kurze stichwortartige Beschreibungen, die diesen so gut wie möglich charakterisieren. Abhängig vom Umfang des Blogsystems sollte die Anzahl der Tags immer in einem gewissen Rahmen vorhanden sein. Das bedeutet zum einen, dass Ersteller von Artikeln immer die gleich Menge der Schlagwörter verwenden, wobei geringe Abweichungen möglich sind (vgl. [Gmb18]). Hat das System bereits einen grö"seren Umfang angenommen, sollten zum Anderen keine neuen Tags erstellt werden um die Übersicht für Autoren und Leser zu bewahren. \\

\begin{figure}[!h]
\centering
\includegraphics[width=1\textwidth]{figures/filtern}
\caption{Prototyp Suche- und Abonnier-Seite}
\hfill
\end{figure} 

Im Prototyp findet man die Abonnement-Funktion unter dem Menüpunkt \texttt{Suche}. Hier erscheint ein zwei-geteiltes Layout, welches auf der rechten Seite alle bereits abonnierten Tags auflistet und darunter die Eingabe eines neuen Tags ermöglicht. Um den Benutzer alle bereits existierenden Tags offen zu legen, befindet sich auf der linken Seite des Layout eine \textit{Tag-Cloud} \footnote{ Tag-Cloud ist eine Visualisierung eines Schlagwortverzeichnisses.}
, die diese darstellt (vgl. Abbildung 3.7.).


Die Eingabe des zu abonnierenden Tags wird durch ein Formular realisiert. Dieses ist in der \texttt{forms.py} Datei konfiguriert und enthält nur ein Eingabefeld. Der Ablauf verläuft gleichartig zum oben dargestellten Erstellen eines Artikels, wird allerdings genauer beschrieben um die Struktur des \texttt{Taggable Managers} zu verdeutlichen. 

\begin{figure}[!h]
\centering
\includegraphics[width=1.1\textwidth]{figures/view-search-add}
\caption{Funktion search\_add, Auszug aus views.py.}
\hfill
\end{figure} 

Gibt der Benutzer einen Tag ein und sendet durch betätigen des Sichern-Buttons den \texttt{Request}, wird dieser in der \texttt{views.py}, verarbeitet. In Zeile 159 der Abbildung 3.8. wird der eingeloggte Benutzer der Variable \texttt{user\_instance} übergeben. Beim Erstellen der \texttt{Model-Instanz}  (vgl. Abbildung 3.8., Zeile 161) wird \texttt{user\_instance} der Unbekannten \texttt{form} zugeteilt um die Tag-Eingabe im richtigen User-Objekt integrieren zu können. Nach der Abfrage der Formvalidität, wird ein neues Objekt angelegt (vgl. Abbildung 3.8., Zeile 163) und ebenfalls dem aktuellen Benutzer zugeordnet. Die Eingabe der \texttt{form} wird in einem \texttt{Array} zwischengespeichert und mit dem Attribut \texttt{cleaned\_data} in ein für Python kompatiblen Datentyp gecastet. Um prüfen zu können, ob die Eingaben der Form tatsächlich im \texttt{Tag-Model} enthalten sind, wird diese nochmals in einen String umgewandelt und mit den bereits existierenden Tags abgeglichen (vgl. Abbildung 3.8., Zeile 168). Wird die Bedingung erfüllt, speichert die Funktion die Tags. In beiden möglichen Fällen, wird der Benutzer benachrichtigt ob der Vorgang erfolgreich oder die Eingabe nicht valide ist.

Nun werden auf dem Dashboard Artikel der neu hinzugefügten Tags angezeigt (vgl Abbildung 3.9.).\\

\begin{figure}[!h]
\centering
\includegraphics[width=1\textwidth]{figures/newsfeed}
\caption{Prototyp Newsfeed Seite}
\hfill
\end{figure} 


\subsection{Filtern}

Zur Unterstützung der Nutzbarkeit des Prototypen ist es wichtig, dass User intuitiv nach Tags suchen und diese selektieren können. Hierfür werden verschiedene Möglichkeiten zur Verfügung gestellt, die die Usability der Website verbessern sollen.

Im persönlichen Newsfeed des Dashboards sind die zu den Artikeln zugewiesenen Schlagwörter jeweils mit Verlinkungen versehen. Möchte ein Benutzer weitere Artikel zu einem bestimmten Thema lesen, so muss er lediglich auf den entsprechenden Tag klicken und erhält somit eine Liste aller Beiträge, die diesen enthalten. Hierfür wird keine eigene \texttt{View} benötigt denn das Erstellen von Listen mit unterschiedlichem Inhalt kann ebenso über sich unterscheidende Urls realisiert werden. Im Template \texttt{post\_list} wird beim Klicken auf einen Tag der \textit{Slug} \footnote{ Der Slug dient im Taggable-Manager als eindeutig zuweisbarer Identifikator.}
dessen mitgegeben. Au"serdem wird nun die Url \texttt{post\_list\_by\_tag} aufgerufen, die auf eine neue Seite verweist. Die View \texttt{post\_list} rendert bei Anfragen mit \textit{Slug} die passende Liste, bei Anfragen ohne, werden alle vorhandenen Artikel geladen.


Der Prototyp bieten zudem die Möglichkeit nach Tags direkt zu suchen. Unter dem Menüpunkt \texttt{Suche} ist auf der linken Seite des geteilten Layouts befindet sich, wie bereits beschrieben, eine \textit{Tag-Cloud}. Darunter ist das Suchfeld, welches durch ein Formular im Template realisiert wird. Da dieses jedoch nur Tags aus der Datenbank abfragt und keine Daten verändert wird hier lediglich ein \texttt{GET-Request} gesendet. Mit der Funktion \texttt{filter} und dem von der taggit-Bibliothek zur Verfügung gestellten \textit{Lookup} \footnote{ Lookup ist eine Art Funktion, die den Ort des darauffolgend Feldes ausgibt.}
\texttt{tags\_\_name\_\_in} können alle Artikel mit dem jeweilig enthaltenen Tag dem Template übergeben werden.







