Browse Source

edited by lena

master
Esther Kleinhenz 6 years ago
parent
commit
97b1b47d6d

+ 1
- 1
doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/bachelorabeit_EstherKleinhenz.lof View File

\contentsline {figure}{\numberline {2.2}{\ignorespaces Request-Response-Kreislauf des Django Frameworks [Nev15].\relax }}{7}{figure.caption.5} \contentsline {figure}{\numberline {2.2}{\ignorespaces Request-Response-Kreislauf des Django Frameworks [Nev15].\relax }}{7}{figure.caption.5}
\contentsline {figure}{\numberline {2.3}{\ignorespaces Erstellen der virtuelle Umgebung im Terminal.\relax }}{8}{figure.caption.6} \contentsline {figure}{\numberline {2.3}{\ignorespaces Erstellen der virtuelle Umgebung im Terminal.\relax }}{8}{figure.caption.6}
\contentsline {figure}{\numberline {2.4}{\ignorespaces Beispiel eines LDAP-Trees [Orc10].\relax }}{9}{figure.caption.7} \contentsline {figure}{\numberline {2.4}{\ignorespaces Beispiel eines LDAP-Trees [Orc10].\relax }}{9}{figure.caption.7}
\contentsline {figure}{\numberline {2.5}{\ignorespaces Einbindung von Bootstrap in einer HTML-Datei.\relax }}{13}{figure.caption.8}
\contentsline {figure}{\numberline {2.5}{\ignorespaces Einbindung von Bootstrap in einer HTML-Datei\relax }}{13}{figure.caption.8}
\contentsline {figure}{\numberline {2.6}{\ignorespaces Bootstrap-Klassen in HTML-Tag\relax }}{13}{figure.caption.9} \contentsline {figure}{\numberline {2.6}{\ignorespaces Bootstrap-Klassen in HTML-Tag\relax }}{13}{figure.caption.9}
\addvspace {10\p@ } \addvspace {10\p@ }
\contentsline {figure}{\numberline {3.1}{\ignorespaces Forschungsdesign\relax }}{15}{figure.caption.10} \contentsline {figure}{\numberline {3.1}{\ignorespaces Forschungsdesign\relax }}{15}{figure.caption.10}

+ 110
- 111
doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/bachelorabeit_EstherKleinhenz.log View File

This is XeTeX, Version 3.14159265-2.6-0.99999 (TeX Live 2018) (preloaded format=xelatex 2018.6.7) 3 DEC 2018 22:45
This is XeTeX, Version 3.14159265-2.6-0.99999 (TeX Live 2018) (preloaded format=xelatex 2018.6.7) 5 DEC 2018 12:02
entering extended mode entering extended mode
\write18 enabled. \write18 enabled.
file:line:error style messages enabled. file:line:error style messages enabled.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 85.
(babel) in language on input line 82.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 85.
(babel) in language on input line 82.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 85.
(babel) in language on input line 82.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 85.
(babel) in language on input line 82.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 85.
(babel) in language on input line 82.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 85.
(babel) in language on input line 82.
[9] [9]
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 89.
(babel) in language on input line 86.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 89.
(babel) in language on input line 86.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 89.
(babel) in language on input line 86.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 93.
(babel) in language on input line 90.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 93.
(babel) in language on input line 90.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 93.
(babel) in language on input line 90.




Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 95.
(babel) in language on input line 92.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 95.
(babel) in language on input line 92.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 95.
(babel) in language on input line 92.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 95.
(babel) in language on input line 92.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 95.
(babel) in language on input line 92.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 95.
(babel) in language on input line 92.
[10] [10]
Underfull \hbox (badness 10000) in paragraph at lines 98--100
Underfull \hbox (badness 10000) in paragraph at lines 95--97


[] []




Underfull \hbox (badness 10000) in paragraph at lines 101--104
Underfull \hbox (badness 10000) in paragraph at lines 98--101


[] []


Missing character: There is no ˜ in font aer12! Missing character: There is no ˜ in font aer12!
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 109.
(babel) in language on input line 106.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 109.
(babel) in language on input line 106.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 109.
(babel) in language on input line 106.


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 113.
(babel) in language on input line 110.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 113.
(babel) in language on input line 110.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 113.
(babel) in language on input line 110.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 113.
(babel) in language on input line 110.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 113.
(babel) in language on input line 110.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 113.
(babel) in language on input line 110.
[11] [11]
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 117.
(babel) in language on input line 114.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 117.
(babel) in language on input line 114.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 117.
(babel) in language on input line 114.




Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 123.
(babel) in language on input line 120.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 123.
(babel) in language on input line 120.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 123.
(babel) in language on input line 120.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 123.
(babel) in language on input line 120.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 123.
(babel) in language on input line 120.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 123.
(babel) in language on input line 120.
[12] [12]
File: figures/bootstrap-head-tag.png Graphic file (type bmp) File: figures/bootstrap-head-tag.png Graphic file (type bmp)
<figures/bootstrap-head-tag.png> <figures/bootstrap-head-tag.png>
LaTeX Warning: `!h' float specifier changed to `!ht'. LaTeX Warning: `!h' float specifier changed to `!ht'.




Underfull \hbox (badness 10000) in paragraph at lines 73--75

[]


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
We now make it that large for the rest of the document. We now make it that large for the rest of the document.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 75.
(babel) in language on input line 72.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 75.
(babel) in language on input line 72.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 75.
(babel) in language on input line 72.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 75.
(babel) in language on input line 72.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 75.
(babel) in language on input line 72.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 75.
(babel) in language on input line 72.
[16] [16]
Underfull \hbox (badness 10000) in paragraph at lines 73--75

[]



Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
[] []




Underfull \hbox (badness 10000) in paragraph at lines 122--126

[]


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
We now make it that large for the rest of the document. We now make it that large for the rest of the document.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 126.
(babel) in language on input line 122.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 126.
(babel) in language on input line 122.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 126.
(babel) in language on input line 122.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 126.
(babel) in language on input line 122.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 126.
(babel) in language on input line 122.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 126.
(babel) in language on input line 122.
[20] [20]
Underfull \hbox (badness 10000) in paragraph at lines 122--126

[]

File: figures/postedit.png Graphic file (type bmp) File: figures/postedit.png Graphic file (type bmp)
<figures/postedit.png> <figures/postedit.png>


This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 162.
(babel) in language on input line 160.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 162.
(babel) in language on input line 160.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 162.
(babel) in language on input line 160.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 162.
(babel) in language on input line 160.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 162.
(babel) in language on input line 160.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 162.
(babel) in language on input line 160.
[22] [22]
File: figures/view-search-add.png Graphic file (type bmp) File: figures/view-search-add.png Graphic file (type bmp)
<figures/view-search-add.png> <figures/view-search-add.png>


[] []


File: figures/newsfeed.png Graphic file (type bmp)
<figures/newsfeed.png>

LaTeX Warning: `!h' float specifier changed to `!ht'.

Package babel Info: Redefining german shorthand "f
(babel) in language on input line 183.
Package babel Info: Redefining german shorthand "|
(babel) in language on input line 183.
Package babel Info: Redefining german shorthand "~
(babel) in language on input line 183.


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 186.
(babel) in language on input line 174.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 186.
(babel) in language on input line 174.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 186.
(babel) in language on input line 174.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 186.
(babel) in language on input line 174.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 186.
(babel) in language on input line 174.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 186.
(babel) in language on input line 174.
[23] [23]
File: figures/newsfeed.png Graphic file (type bmp)
<figures/newsfeed.png>


LaTeX Warning: `!h' float specifier changed to `!ht'.

Package babel Info: Redefining german shorthand "f
(babel) in language on input line 183.
Package babel Info: Redefining german shorthand "|
(babel) in language on input line 183.
Package babel Info: Redefining german shorthand "~
(babel) in language on input line 183.


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
Make it at least 14.49998pt. Make it at least 14.49998pt.
This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 193.
(babel) in language on input line 190.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 193.
(babel) in language on input line 190.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 193.
(babel) in language on input line 190.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 193.
(babel) in language on input line 190.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 193.
(babel) in language on input line 190.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 193.
(babel) in language on input line 190.
[24]) [24])


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
(babel) in language on input line 1. (babel) in language on input line 1.


Package hyperref Warning: Difference (2) between bookmark levels is greater Package hyperref Warning: Difference (2) between bookmark levels is greater
(hyperref) than one, level fixed on input line 15.
(hyperref) than one, level fixed on input line 17.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 15.
(babel) in language on input line 17.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 15.
(babel) in language on input line 17.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 15.
(babel) in language on input line 17.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 19.
(babel) in language on input line 21.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 19.
(babel) in language on input line 21.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 19.
(babel) in language on input line 21.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 19.
(babel) in language on input line 21.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 19.
(babel) in language on input line 21.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 19.
(babel) in language on input line 21.
[32 [32








] ]
Underfull \hbox (badness 10000) in paragraph at lines 21--23
Underfull \hbox (badness 10000) in paragraph at lines 23--25


[] []


This may cause the page layout to be inconsistent, however. This may cause the page layout to be inconsistent, however.


Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 38.
(babel) in language on input line 40.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 38.
(babel) in language on input line 40.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 38.
(babel) in language on input line 40.
Package babel Info: Redefining german shorthand "f Package babel Info: Redefining german shorthand "f
(babel) in language on input line 38.
(babel) in language on input line 40.
Package babel Info: Redefining german shorthand "| Package babel Info: Redefining german shorthand "|
(babel) in language on input line 38.
(babel) in language on input line 40.
Package babel Info: Redefining german shorthand "~ Package babel Info: Redefining german shorthand "~
(babel) in language on input line 38.
(babel) in language on input line 40.
[33]) [33])


Package Fancyhdr Warning: \headheight is too small (12.0pt): Package Fancyhdr Warning: \headheight is too small (12.0pt):
) )
(\end occurred when \ifnum on line 5 was incomplete) (\end occurred when \ifnum on line 5 was incomplete)
Here is how much of TeX's memory you used: Here is how much of TeX's memory you used:
27443 strings out of 492970
491377 string characters out of 6133939
27444 strings out of 492970
491391 string characters out of 6133939
562191 words of memory out of 5000000 562191 words of memory out of 5000000
31004 multiletter control sequences out of 15000+600000
31005 multiletter control sequences out of 15000+600000
559401 words of font info for 77 fonts, out of 8000000 for 9000 559401 words of font info for 77 fonts, out of 8000000 for 9000
1348 hyphenation exceptions out of 8191 1348 hyphenation exceptions out of 8191
58i,18n,50p,10437b,960s stack positions out of 5000i,500n,10000p,200000b,80000s
58i,18n,50p,10437b,966s stack positions out of 5000i,500n,10000p,200000b,80000s


Output written on /Users/Esthi/thesis_ek/doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/bachelorabeit_EstherKleinhenz.pdf (42 pages). Output written on /Users/Esthi/thesis_ek/doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/bachelorabeit_EstherKleinhenz.pdf (42 pages).

BIN
doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/bachelorabeit_EstherKleinhenz.synctex.gz View File


+ 1
- 1
doc/bachelorarbeit_EstherKleinhenz/.texpadtmp/chapters/framework.aux View File

\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}Taggable-Manager}{10}{subsection.2.2.1}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}Taggable-Manager}{10}{subsection.2.2.1}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}Hilfsbibliotheken}{11}{subsection.2.2.2}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}Hilfsbibliotheken}{11}{subsection.2.2.2}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Bootstrap}{12}{section.2.3}} \@writefile{toc}{\contentsline {section}{\numberline {2.3}Bootstrap}{12}{section.2.3}}
\@writefile{lof}{\contentsline {figure}{\numberline {2.5}{\ignorespaces Einbindung von Bootstrap in einer HTML-Datei.\relax }}{13}{figure.caption.8}}
\@writefile{lof}{\contentsline {figure}{\numberline {2.5}{\ignorespaces Einbindung von Bootstrap in einer HTML-Datei\relax }}{13}{figure.caption.8}}
\@writefile{lof}{\contentsline {figure}{\numberline {2.6}{\ignorespaces Bootstrap-Klassen in HTML-Tag\relax }}{13}{figure.caption.9}} \@writefile{lof}{\contentsline {figure}{\numberline {2.6}{\ignorespaces Bootstrap-Klassen in HTML-Tag\relax }}{13}{figure.caption.9}}
\@setckpt{chapters/framework}{ \@setckpt{chapters/framework}{
\setcounter{page}{14} \setcounter{page}{14}

BIN
doc/bachelorarbeit_EstherKleinhenz/bachelorabeit_EstherKleinhenz.pdf View File


+ 32
- 35
doc/bachelorarbeit_EstherKleinhenz/chapters/framework.tex View File

\chapter{Framework} \chapter{Framework}
\label{ch:framework} \label{ch:framework}
Um die Website-Erweiterung realisieren zu können, wird zunächst festgelegt welche Programmierschnittstellen verwendet werden. Im Web-Backend fällt die Wahl auf die objektorientierte Sprache Python, die Serverseitig anwendbar ist. Der Programmaufbau Pythons macht den Code leicht lesbar und der einfache Syntax ermöglicht einen strukturierte Implementierung der Website (vgl. [Ndu17]). Durch den modularen Aufbau ist es selbst für unerfahrene Entwickler möglich die Sprache schnell zu erlernen. Darüber hinaus bringt Python verschiedene Web-Service Tools mit sich, die beim Implementieren einer Website viel Zeit sparen und das Aneignen von komplexen Protokollen redundant machen (vgl. [Sol17]).
Um die Website-Erweiterung realisieren zu können, wird zunächst festgelegt, welche Programmierschnittstellen verwendet werden. Im Web-Backend fällt die Wahl auf die objektorientierte Sprache Python, die serverseitig anwendbar ist. Der Programmaufbau Pythons macht den Code leicht lesbar und die einfache Syntax ermöglicht eine strukturierte Implementierung der Website (vgl. [Ndu17]). Durch den modularen Aufbau ist es selbst für unerfahrene Entwickler möglich, die Sprache schnell zu erlernen. Darüber hinaus bringt Python verschiedene Web-Service Tools mit sich, die beim Implementieren einer Website viel Zeit sparen und das Aneignen von komplexen Protokollen redundant machen (vgl. [Sol17]).
Das dazugehörige Framework Django reduziert den Entwicklungsaufwand eines Prototypen erheblich und ist daher als zielführendes Framework die beste Wahl. Das dazugehörige Framework Django reduziert den Entwicklungsaufwand eines Prototypen erheblich und ist daher als zielführendes Framework die beste Wahl.


\section{Django} \section{Django}
Django ist ein Web-Framework, das eine schnelle, strukturierte Entwicklung ermöglicht und dabei ein einfaches Design beibehält. Der darin enthaltene Model-View-Presenter (MVP) kann, ähnlich wie der Model-View-Controller, die Interaktionen zwischen Model und View, die Auswahl und Ausführung von Befehlen und das Auslösen von Ereignissen steuern (vgl. Abbildung 2.1). Da die View aber hier bereits den Gro"steil des Controllers übernimmt, ist der MVP eine Überarbeitung. Der Teil, der Elemente des Modells auswählt, Operationen durchführt und alle Ereignisse kapselt, ergibt die Presenter-Klasse (vgl. [She09]). Durch die direkte Bindung von Daten und der View, geregelt durch den Pfresenter, wird die Codemenge der Applikation stark reduziert.
Django ist ein Web-Framework, das eine schnelle, strukturierte Entwicklung ermöglicht und dabei ein einfaches Design beibehält. Der darin enthaltene Model-View-Presenter (MVP) kann, ähnlich wie der Model-View-Controller, die Interaktionen zwischen Model und View, die Auswahl und Ausführung von Befehlen und das Auslösen von Ereignissen steuern (vgl. Abbildung 2.1). Da die View aber hier bereits den Gro"steil des Controllers übernimmt, ist der MVP eine Überarbeitung. Der Teil, der Elemente des Modells auswählt, Operationen durchführt und alle Ereignisse kapselt, ergibt die Presenter-Klasse (vgl. [She09]). Durch die direkte Bindung von Daten und der View, geregelt durch den Presenter, wird die Codemenge der Applikation stark reduziert.


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \end{figure}


Der Prozess vom Anfragen der URL über den Server, bis hin zur fertig gerenderten Website kann wie folgt vereinfacht dargestellt werden.
Der Prozess vom Anfragen der URL über den Server bis hin zur fertig gerenderten Website kann wie folgt vereinfacht dargestellt werden.


Der User gibt eine URL im Browser ein und sendet sie an den Web-Server. Das Interface WSGI (Web Server Gateway Interface) am Web-Server verbindet diesen mit dem Web-Framework, indem es den Request zum passenden Objekt weiterleitet. Hier wird der Applikation eine Callback-Funktion zur Verfügung gestellt (vgl. [Kin17]). Au"serdem werden folgende Schritte durchgeführt: Der User gibt eine URL im Browser ein und sendet sie an den Web-Server. Das Interface WSGI (Web Server Gateway Interface) am Web-Server verbindet diesen mit dem Web-Framework, indem es den Request zum passenden Objekt weiterleitet. Hier wird der Applikation eine Callback-Funktion zur Verfügung gestellt (vgl. [Kin17]). Au"serdem werden folgende Schritte durchgeführt:
\begin{itemize} \begin{itemize}
\end{itemize} \end{itemize}


Der WSGI-Handler fungiert als Pförtner und Manager zwischen dem Web-Server und dem Django-Projekt. Der WSGI-Handler fungiert als Pförtner und Manager zwischen dem Web-Server und dem Django-Projekt.
Um die URL, wie weiter oben erwähnt, aufzulösen, benötigt WSGI einen \textit {urlresolver}\footnote{ Urlsresolver verknüpft Url-Muster mit den passenden Views.}
(vgl. [Dja18b]). Durch die explizite Zuweisung der vorhandenen Seiten, kann dieser über die regulären Ausdrücke der url.py-Datei iterieren. Gibt es eine Übereinstimmung, wird die damit verknüpfte Funktion in der View (views.py) aufgerufen. Hier ist die gesamte Logik der Website lokalisiert. Es ist möglich unter Anderem auf die Datenbank der Applikation zuzugreifen und Eingaben des Users über eine Form zu verarbeiten. Nachdem werden die Informationen der View an das Template weitergereicht. Es handelt sich dabei um eine einfache HTML-Seite in der der strukturelle Aufbau im Front-end festgelegt wird. Die Informationen der View können hier zwischen doppelt-geschweiften Klammern eingebunden und, wenn nötig, mit einfachen Python-Befehlen angepasst werden. Das Template kann dann die vom WSGI-Framework zur Verfügung gestellte Callback-Funktion befüllen und einen Response an den Web-Server schicken. Die fertige Seite ist beim Klienten im Browserfenster zum rendern bereit (vgl. [Kin17], Abbildung 2.2.).
Um die URL aufzulösen, benötigt WSGI einen \textit {urlresolver}\footnote{ Urlsresolver verknüpft Url-Muster mit den passenden Views.}
(vgl. [Dja18b]). Durch die explizite Zuweisung der vorhandenen Seiten kann dieser über die regulären Ausdrücke der url.py-Datei iterieren. Gibt es eine Übereinstimmung, wird die damit verknüpfte Funktion in der View (views.py) aufgerufen. Hier ist die gesamte Logik der Website lokalisiert. Unter anderem ist es möglich auf die Datenbank der Applikation zuzugreifen und Eingaben des Users über eine Form zu verarbeiten. Anschlie"send werden die Informationen der View an das Template weitergereicht. Es handelt sich dabei um eine einfache HTML-Seite, in der der strukturelle Aufbau im Front-end festgelegt wird. Die Informationen der View können hier zwischen doppelt-geschweiften Klammern eingebunden und, wenn nötig, mit einfachen Python-Befehlen angepasst werden. Das Template kann dann die vom WSGI-Framework zur Verfügung gestellte Callback-Funktion befüllen und eine Response an den Web-Server schicken. Die fertige Seite ist beim Klienten im Browserfenster zum Rendern bereit (vgl. [Kin17], Abbildung 2.2.).


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\end{figure} \end{figure}


\subsection {Besonderheiten Djangos} \subsection {Besonderheiten Djangos}
Das Django-Framework bringt einige Besonderheiten mit sich, die beim Implementiern des Prototypen von Bedeutung sind. Diese werden im Folgenden beschrieben.
Das Django-Framework bringt einige Besonderheiten mit sich, die beim Implementieren des Prototypen von Bedeutung sind. Diese werden im Folgenden beschrieben.


Die Administratoroberfläche ist eines der hilfreichsten Werkzeugen des gesamten Frameworks. Es stellt die Metadaten der Modelle aus dem Code visuell dar. Verifizierte Benutzer können die Daten nicht nur schnell erfassen, sondern diese auch editieren und verwalten. Das Recht, das Admin-Backend uneingeschränkt zu benutzen, ist dem \textit{Superuser}\footnote{ Superuser ist ein Benutzer der alle Zugangsrechte im Framework erhält.} vorenthalten. Dieser kann beim erstmaligen Zuweisen nur über die Kommandozeile eingerichtet werden. Ist bereits ein Superuser vorhanden, kann dieser im Admin-Backend weiteren Benutzern den gleichen Handlungsfreiraum einräumen. Zudem gibt es noch weitere Stufen der Zugangsberechtigungen, Staff- und Active-Status, die für eine breitere Gruppe von Benutzern geeignet ist.
Um die gestaffelten Zugangsberechtigungen auch auf der Website umsetzen zu können, stellt Django verschiedene Dekoratoren zur Verfügung. Soll eine bestimmte Seite nur von authentifizierten Benutzern besucht werden, kann die Funktion mit einem Decorator versehen werden:
Die Administratoroberfläche ist eines der hilfreichsten Werkzeugen des gesamten Frameworks. Es stellt die Metadaten der Modelle aus dem Code visuell dar. Verifizierte Benutzer können die Daten nicht nur schnell erfassen, sondern diese auch editieren und verwalten. Das Recht, das Admin-Backend uneingeschränkt zu nutzen, ist dem \textit{Superuser}\footnote{ Superuser ist ein Benutzer, der alle Zugangsrechte im Framework erhält.} vorenthalten. Dieser kann beim erstmaligen Zuweisen nur über die Kommandozeile eingerichtet werden. Ist bereits ein Superuser vorhanden, kann dieser im Admin-Backend weiteren Benutzern den gleichen Handlungsfreiraum einräumen. Zudem gibt es noch weitere Stufen der Zugangsberechtigungen, Staff- und Active-Status, die für eine breitere Gruppe von Benutzern geeignet ist.
Um die gestaffelten Zugangsberechtigungen auch auf der Website umsetzen zu können, stellt Django verschiedene Dekoratoren zur Verfügung. Soll eine bestimmte Seite nur von authentifizierten Benutzern besucht werden können, kann die Funktion mit einem Decorator versehen werden:
\\ \\
\begin{addmargin}[0pt]{0pt} \begin{addmargin}[0pt]{0pt}
\noindent\hspace*{10mm}% \noindent\hspace*{10mm}%
\texttt{\makeatletter @login\_required} \texttt{\makeatletter @login\_required}
\\ \\
\end{addmargin} \end{addmargin}
Natürlich lassen sich Dekoratoren auch für andere Zwecke vor Funktionen platzieren. Unter Anderem werden so die Views vor möglichen Angriffen, wie Cross-Site-Scripting, geschützt.
Natürlich lassen sich Dekoratoren auch für andere Zwecke vor Funktionen platzieren. Unter anderem werden so die Views vor möglichen Angriffen, wie Cross-Site-Scripting, geschützt.


Durch den einfachen Aufbau ist es au"serdem möglich diese selbst zu implementieren. Ein einfaches Beispiel wäre das prüfen des, an die Funktion übergebenen, Parameter. Sollen nur positive Zahlen verarbeitet werden, so kann der Decorator alle anderen Eingaben abfangen.
Durch den einfachen Aufbau ist es au"serdem möglich, diese selbst zu implementieren. Ein einfaches Beispiel wäre das Prüfen des an die Funktion übergebenen Parameter. Sollen nur positive Zahlen verarbeitet werden, so kann der Decorator alle anderen Eingaben abfangen.




\subsection{Virtuelle Umgebung} \subsection{Virtuelle Umgebung}


Wird eine prototypische Anwendung gestartet, ist es notwendig, verschiedensten Module zu verwenden und zu testen. Die Versionen dieser spielen hierbei eine entscheidende Rolle, um Konflikte zu vermeiden (vgl. [Fou18]). Um diesem Problem vorzubeugen, wird eine virtuelle Umgebung implementiert. Sie besitzt einen eigenen Projektpfad, beinhaltet alle nötigen Pakete und Bibliotheken, und lässt sich nach dem Einrichten im Terminal starten. Die folgende Abbildung 2.4. zeigt das Erstellen eines neuen Ordners, das Erstellen der virtuellen Umgebung und den Aktivierungsbefehl. Ist der Name des Environment in Klammern am Kommandozeilenanfang, bedeutet das, diese ist jetzt aktiv.
Wird eine prototypische Anwendung gestartet, ist es notwendig, verschiedenste Module zu verwenden und zu testen. Die Versionen dieser Module spielen hierbei eine entscheidende Rolle, um Konflikte zu vermeiden (vgl. [Fou18]). Um diesem Problem vorzubeugen, wird eine virtuelle Umgebung implementiert. Sie besitzt einen eigenen Projektpfad, beinhaltet alle nötigen Pakete und Bibliotheken, und lässt sich nach dem Einrichten im Terminal starten. Abbildung 2.3. zeigt das Erstellen eines neuen Ordners, das Erstellen der virtuellen Umgebung und den Aktivierungsbefehl. Ist der Name des Environments in Klammern am Kommandozeilenanfang, bedeutet das, dass diese jetzt aktiv ist.


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \end{figure}


Um die Pakete und Module kollisionsfrei zu installieren ist es empfehlenswert einen Package-Manager zu verwenden. Mit \textit{pip}\footnote{ pip ist das rekursive Akronym für pip Install Packages. } (vgl. [Wei17, K. 23.1]), können diese installiert, geupdated und gelöscht werden. Au"serdem kann der Manager Abhängigkeiten, wenn nötig, überschreiben und optimieren. Falls ein, sich von der neuesten Version unterscheidendes, Programm installiert werden soll, so ist dies ebenso möglich.
Um die Pakete und Module kollisionsfrei zu installieren, ist es empfehlenswert, einen Package-Manager zu verwenden. Mit \textit{pip}\footnote{ pip ist das rekursive Akronym für pip Install Packages. } (vgl. [Wei17, K. 23.1]) können diese installiert, geupdated und gelöscht werden. Au"serdem kann der Manager Abhängigkeiten, wenn nötig, überschreiben und optimieren. Falls ein sich von der neuesten Version unterscheidendes Programm installiert werden soll, so ist dies ebenso möglich.


\subsection{Lightweight Directory Access Protocol} \subsection{Lightweight Directory Access Protocol}


Das ldap, Lightweight Directory Access Protocol, muss als Erweiterung in die hier bearbeitende Bachelor-Arbeit eingebunden werden, um später die Login-Daten im Hochschulinternen Netz abfragen zu können. Dies ist ein Internetprotokoll, welches die Kommunikation mit dem Active Directory verwaltet. Es wird eingesetzt um Benutzer so schnell und effizient wie möglich durch eine bereits existierende Datenbank abzufragen und zu authentifizieren. Der Aufbau ist mit einem Baum zu vergleichen (vgl. Abbildung 2.4.). Die Wurzel besteht aus sehr allgemeinen Informationen, umso näher man den Blättern kommt, umso spezifischer werden diese. Ein Objekt in der Struktur wird durch einen einmaligen Namen identifiziert, der aus den gesamten hinterlegten Informationen besteht. Der Name für den in der Abbildung 2.4 dargestellten Baum wäre \texttt{cn=John Doe, ou=People, dc=sun.com} (vgl. [Sch17]).
Das ldap, Lightweight Directory Access Protocol, muss als Erweiterung in die hier bearbeitende Bachelor-Arbeit eingebunden werden, um später die Login-Daten im Hochschulinternen Netz abfragen zu können. Dies ist ein Internetprotokoll, welches die Kommunikation mit dem Active Directory verwaltet. Es wird eingesetzt, um Benutzer so schnell und effizient wie möglich durch eine bereits existierende Datenbank abzufragen und zu authentifizieren. Der Aufbau ist mit einem Baum zu vergleichen (vgl. Abbildung 2.4.). Die Wurzel besteht aus sehr allgemeinen Informationen, umso näher man den Blättern kommt, umso spezifischer werden diese. Ein Objekt in der Struktur wird durch einen einmaligen Namen identifiziert, der aus den gesamten hinterlegten Informationen besteht. Der Name für den in Abbildung 2.4 dargestellten Baum wäre \texttt{cn=John Doe, ou=People, dc=sun.com} (vgl. [Sch17]).


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\end{figure} \end{figure}


\subsection{Sicherheit} \subsection{Sicherheit}
Beim Implementieren einer Website ist das Absichern vor schädlichen Attacken heutzutage unabdingbar. Django aktiviert einige Funktionen zum Schutz bereits beim Projektstart automatisch. Dazu gehört das Abwehren von \textit{Cross-Site-Scripting}\footnote{ Cross-Site-Scripting kann Webseiten verändern oder Passwörter abgreifen.}
, \textit{SQL-Injektion}\footnote{ SQL-Injection nutzt mangelnde Überprüfung von Metazeichen um Datenbankabfragen zu verändern.}
, \textit{Clickjacking}\footnote{ Clickjacking ist eine Überlagerung von Internetseiten um Klicks zu manipulieren.}
und die Sicherstellung der \textit{Session-Security}\footnote{ Session-Security setzen Cookies auch für Subdomäne beim Client. }
.
Beim Implementieren einer Website ist das Absichern vor schädlichen Attacken heutzutage unabdingbar. Django aktiviert einige Funktionen zum Schutz bereits beim Projektstart automatisch. Dazu gehört das Abwehren von \textit{Cross-Site-Scripting}\footnote{ Cross-Site-Scripting kann Webseiten verändern oder Passwörter abgreifen.}, \textit{SQL-Injektion}\footnote{ SQL-Injection nutzt mangelnde Überprüfung von Metazeichen um Datenbankabfragen zu verändern.}, \textit{Clickjacking}\footnote{ Clickjacking ist eine Überlagerung von Internetseiten um Klicks zu manipulieren.}
und die Sicherstellung der \textit{Session-Security}\footnote{ Session-Security setzen Cookies auch für Subdomäne beim Client. }.


Sollen die Formulare des Prototypen gegen \textit{Cross-Site-Request-Forgery} geschützt werden, muss aktiv ein \textit{Token} im Template gesetzt werden. Sollen die Formulare des Prototypen gegen \textit{Cross-Site-Request-Forgery} geschützt werden, muss aktiv ein \textit{Token} im Template gesetzt werden.


Ein solcher Angriff tritt auf wenn über einen bösartigen Link, eine Formularschaltfläche oder einfach dem eingebettetem JavaScript-Code die Daten im Server verändert werden sollen. Hierbei nutzt der Angreifer die Rechte eines eingeloggten Benutzers und kann somit Informationen im Back-end verfälschen. Um dies zu verhindern wird im Template des Prototypen, zwischen den Form-Tags der \textit{crsf-Token}\footnote{ Token sind Komponente die eine Zugriffskontrolle von Benutzer druchführen können.}
eingefügt. Der Token setzt einen Cookie mit einer verschlüsselten Zufallszahl. Das Gleiche passiert im Template, wo ein, für den Benutzer nicht sichtbares, Form-Feld die gleiche verschlüsselte Zufallszahl erhält. Beide Zahlen erhalten zudem einen \textit{Salt}, ein generierter Zusatzwert, der das entschlüsseln dieser um ein vielfaches erschwert. Wird ein Request gesendet, vergleicht eine von Django initzialisierte \textit{Middleware}\footnote{ Middleware ist ein Plug-in, dass Anfrage- und Antwortverarbeitung durchführt.} beide Zahlen. Sind diese nicht gleich, hat also ein Dritter die Informationen manipuliert, wird der 403 HTTP-Standart-Statuscode gesendet, welcher besagt, dass der Server eine Anfrage erhalten hat, diese aber nicht erfüllen wird.
Der \texttt{crsf-Token} greift nur wenn der POST-Request innerhalb der eigenen Website gesendet wird und nicht über URLs, die au"serhalb des Frameworks liegen (vgl. [Fou18a]).
Ein solcher Angriff tritt auf, wenn über einen bösartigen Link, eine Formularschaltfläche oder einfach den eingebettetem JavaScript-Code die Daten im Server verändert werden sollen. Hierbei nutzt der Angreifer die Rechte eines eingeloggten Benutzers und kann somit Informationen im Back-end verfälschen. Um dies zu verhindern, wird im Template des Prototypen zwischen den Form-Tags der \textit{crsf-Token}\footnote{ Token sind Komponente die eine Zugriffskontrolle von Benutzer druchführen können.}
eingefügt. Der Token setzt einen Cookie mit einer verschlüsselten Zufallszahl. Das Gleiche passiert im Template, wo ein für den Benutzer nicht sichtbares Form-Feld die gleiche verschlüsselte Zufallszahl erhält. Beide Zahlen erhalten zudem einen \textit{Salt}, einen generierten Zusatzwert, der das Entschlüsseln dieser um ein vielfaches erschwert. Wird ein Request gesendet, vergleicht eine von Django initialisierte \textit{Middleware}\footnote{ Middleware ist ein Plug-in, dass Anfrage- und Antwortverarbeitung durchführt.} beide Zahlen. Stimmen diese nicht überein, hat also ein Dritter die Informationen manipuliert, wird der 403 HTTP-Standard-Statuscode gesendet, welcher besagt, dass der Server eine Anfrage erhalten hat, diese aber nicht erfüllen wird.
Der \texttt{crsf-Token} greift nur, wenn der POST-Request innerhalb der eigenen Website gesendet wird und nicht über URLs, die au"serhalb des Frameworks liegen (vgl. [Fou18a]).


\section {Erweiterungen} \section {Erweiterungen}
Django bringt viele hilfreiche Erweiterungen mit sich, die mit einem Packagemanager einfach in die virtuelle Umgebung geladen werden können. Um das passende Add-on für ein Projekt zu finden, bietet die Plattform djangopackages.org alle Erweiterungen in übersichtlichen Tabellen mit Eigenschaften und Bewertung an. Eine Vielzahl an Bibliotheken wurden für diese Arbeit getestet, aber wegen mangelnder Kompatibilität oder Funktionalität als nicht hilfreich erachtet und werden deshalb hier nicht weiter erwähnt.
Django bringt viele hilfreiche Erweiterungen mit sich, die mit einem Packagemanager einfach in die virtuelle Umgebung geladen werden können. Um das passende Add-on für ein Projekt zu finden, bietet die Plattform djangopackages.org alle Erweiterungen in übersichtlichen Tabellen mit Eigenschaften und Bewertungen an. Eine Vielzahl an Bibliotheken wurden für diese Arbeit getestet, aber wegen mangelnder Kompatibilität oder Funktionalität als nicht hilfreich erachtet und deshalb hier nicht weiter erwähnt.
Die im Folgenden aufgeführten Bibliotheken sind im Prototyp zur Anwendung gelangt. Die im Folgenden aufgeführten Bibliotheken sind im Prototyp zur Anwendung gelangt.


\subsection {Taggable-Manager} \subsection {Taggable-Manager}
Um die Artikel besser priorisieren und Informationsflut für Benutzer reduzieren zu können, wird im Prototyp mit Schlagwörtern gearbeitet. Django-taggit ist eine Erweiterung, die das Verwenden von Tags vereinfacht. Der darin enthaltene Taggable Manager verwendet Django's Contenttype Framework, welches per Default verwendet wird, um die Modelle der Applikation zu verfolgen und diese durch generische Beziehungen zu verknüpfen. Die Felder \texttt{app\_label} und \texttt{model} machen die Modelle eindeutig zuweisbar. Instanzen des Contenttypes präsentieren und speichern die Informationen und Erstellen automatisch neue Instanzen, wenn Modelle hinzugefügt werden. Zudem stehen Methoden zur Verfügung, die das Abrufen und Arbeiten mit Instanzen der einzelnen Modelle erleichtern.
Um die Artikel besser priorisieren und die Informationsflut für Benutzer reduzieren zu können, wird im Prototyp mit Schlagwörtern gearbeitet. Django-taggit ist eine Erweiterung, die das Verwenden von Tags vereinfacht. Der darin enthaltene Taggable Manager setzt Django's Contenttype Framework ein, welches per Default verwendet wird, um die Modelle der Applikation zu verfolgen und diese durch generische Beziehungen zu verknüpfen. Die Felder \texttt{app\_label} und \texttt{model} machen die Modelle eindeutig zuweisbar. Instanzen des Contenttyps präsentieren und speichern die Informationen und erstellen automatisch neue Instanzen, wenn Modelle hinzugefügt werden. Zudem stehen Methoden zur Verfügung, die das Abrufen und Arbeiten mit Instanzen der einzelnen Modelle erleichtern.


Der Taggable-Manager ist jedoch nicht an das Contenttype-Framework gebunden (vgl. [Her16]). Durch die Verwendung eines echten Fremdschlüssels, kann zum Beispiel die Performance und Referenzgarantie verwirklicht werden. Dazu ist lediglich die Erstellung einer eigenen \textit{Lookup-Tabelle}\footnote{ Eine Lookup-Tabelle speichert Daten statisch im Verhältnis zueinander.} notwendig, die die Entitäten zweier Tabellen direkt verlinkt, anstatt diese generische zu verbinden. Weiterführend können Modelle in einem benutzerdefinierten Modell vereint werden, sodass der Zugriff auf diese einheitlich geschieht. Au"serdem ist es möglich Primary-Keys zu verwenden, die nicht aus ganzen Zahlen bestehen, sondern aus Buchstaben und Wörtern.
Der Taggable-Manager ist jedoch nicht an das Contenttype-Framework gebunden (vgl. [Her16]). Durch die Verwendung eines echten Fremdschlüssels kann zum Beispiel die Performance und Referenzgarantie verwirklicht werden. Dazu ist lediglich die Erstellung einer eigenen \textit{Lookup-Tabelle}\footnote{ Eine Lookup-Tabelle speichert Daten statisch im Verhältnis zueinander.}notwendig, die die Entitäten zweier Tabellen direkt verlinkt, statt sie generisch zu verbinden. Weiterführend können Modelle in einem benutzerdefinierten Modell vereint werden, sodass der Zugriff darauf einheitlich geschieht. Au"serdem ist es möglich, Primary-Keys zu verwenden, die nicht aus ganzen Zahlen bestehen, sondern aus Buchstaben und Wörtern.


Um django-taggit zu installieren wird der folgende Befehl in die Kommandozeile eingefügt (vgl. [Gay10]):
Um django-taggit zu installieren, wird der folgende Befehl in die Kommandozeile eingefügt (vgl. [Gay10]):
\\ \\
\begin{addmargin}[0pt]{0pt} \begin{addmargin}[0pt]{0pt}
\noindent\hspace*{10mm}% \noindent\hspace*{10mm}%
\\ \\
\end{addmargin} \end{addmargin}
Im ˜\texttt{model.py} wird das Feld \texttt{tag} neu erstellt und als Taggable Manager definiert. Im ˜\texttt{model.py} wird das Feld \texttt{tag} neu erstellt und als Taggable Manager definiert.
Au"serdem muss taggit in der \texttt{settings.py} unter \texttt{INSTALLED\_APPS} ergänzt werden. Um dem Programm mitzuteilen, dass nun eine neue Liste der Datenbank hinzugefügt werden muss, werden über die Kommandozeile Migrations-Befehle ausgeführt, die im Kapitel Datenmodellierung genauer beschreiben werden.
Im Admin-Backend kann nun geprüft werden, ob das neue Feld in die Datenbank integriert wurde. Neue Tags können in das Textfeld eingetragen werden. Der Parser verarbeitet jedes Wort, dass durch ein Komma oder ein Leerzeichen getrennt ist als ein Tag. Soll dieses jedoch aus mehreren Wörtern bestehen so müssen diese mit Anführungszeichen umfasst werden. Standardmä"sig unterscheidet der Taggable Manager zwischen Groß- und Kleinschreibung, Tags sind also case sensitive.
Au"serdem muss taggit in der \texttt{settings.py} unter \texttt{INSTALLED\_APPS} ergänzt werden. Um dem Programm mitzuteilen, dass nun eine neue Liste der Datenbank hinzugefügt werden muss, werden über die Kommandozeile Migrations-Befehle ausgeführt, die im Kapitel Datenmodellierung genauer beschrieben werden.
Im Admin-Backend kann nun geprüft werden, ob das neue Feld in die Datenbank integriert wurde und neue Tags können in das Textfeld eingetragen werden. Der Parser verarbeitet jedes Wort, das durch ein Komma oder ein Leerzeichen getrennt ist als einen Tag. Soll dieses jedoch aus mehreren Wörtern bestehen, so müssen diese mit Anführungszeichen umfasst werden. Standardmä"sig unterscheidet der Taggable Manager zwischen Groß- und Kleinschreibung, Tags sind also case sensitive.


\subsection {Hilfsbibliotheken} \subsection {Hilfsbibliotheken}
Weitere Add-ons werden geladen um kleinere Funktionen der Website einfach umsetzen zu können. Zu diesen gehört \texttt{django-taggit-templatetags}, welches durch die Einbindung im HTML-File die Tags der Applikation als Liste ausgibt. Au"serdem lassen sich die eingepflegten Tags als Cloud visualisieren. Kommen bestimmte Schlagwörter öfters vor als andere, so werden sie entsprechend grö"ser dargestellt.
Weitere Add-ons werden geladen, um kleinere Funktionen der Website einfach umsetzen zu können. Zu diesen gehört \texttt{django-taggit-templatetags}, welches durch die Einbindung im HTML-File die Tags der Applikation als Liste ausgibt. Au"serdem lassen sich die eingepflegten Tags als Cloud visualisieren. Kommen bestimmte Schlagwörter öfter vor als andere, so werden sie entsprechend grö"ser dargestellt.


\texttt{Django-hitcount} dient zum zählen der Besucher einer Seite (vgl. [Tim15]). Dies lässt sich auf drei verschiedene Arten in die Applikation einbinden. Der schnellste Weg ist die Darstellung der Besuche mit Hilfe eines Template Tags im HTML-File. Möchte man die Anzeige aber individueller gestalten so kann durch das integrieren der \texttt{HitCountDetailView} in \texttt{views.py} die Variable \texttt{hitcount} verwenden und im Frontend ausgeben. Eine weiter Möglichkeit ist das Erweitern oder neu Erstellen eines Models im Django Backend. Von dort kann auf das neue Feld im Django-Admin-Backend zugegriffen werden, ebenso wie in der View und im Template. Die im Add-on integrierten Einstellungen, die in der \texttt{settings.py} ergänzt werden müssen, ermöglichen unter Anderem das begrenzen der Lebensdauer des Zählers, bevor dieser zurück gesetzt wird.
\texttt{Django-hitcount} dient zum zählen der Besucher einer Seite (vgl. [Tim15]). Es lässt sich auf drei verschiedene Arten in die Applikation einbinden. Der schnellste Weg ist die Darstellung der Besuche mit Hilfe eines Template Tags im HTML-File. Möchte man die Anzeige aber individueller gestalten, so kann durch das integrieren der \texttt{HitCountDetailView} in \texttt{views.py} die Variable \texttt{hitcount} verwenden und im Frontend ausgeben. Eine weitere Möglichkeit ist das Erweitern oder neu Erstellen eines Models im Django Backend. Von dort kann auf das neue Feld im Django-Admin-Backend zugegriffen werden, ebenso wie von der View und vom Template. Die im Add-on integrierten Einstellungen, die in der \texttt{settings.py} ergänzt werden müssen, ermöglichen unter anderem das Begrenzen der Lebensdauer des Zählers, bevor dieser zurück gesetzt wird.


Um das Versenden und Verwalten von E-Mails in Django zu realisieren eignet sich \texttt{django-post-office} (vgl. [Ong18]). Nach der Installation kann im Admin-Backend ein E-Mail-Templates angelegt, Anhänge verwaltet und das Senden dieser im Log überprüft werden. Es ist möglich die Benachrichtigungen asynchron zu versenden mit Hilfe eines Shell-Skript des Frameworks \texttt{Cron}\footnote{ Cron dient zur zeitbasierten Ausführung von definierten Aufgaben.}. Der Inhalt kann Text oder HTML-basiert sein und in mehreren Sprachen hinterlegt werden.
Zum Versenden und Verwalten von E-Mails in Django eignet sich \texttt{django-post-office} (vgl. [Ong18]). Nach der Installation kann im Admin-Backend ein E-Mail-Template angelegt, Anhänge verwaltet und das Versenden dieser im Log überprüft werden. Es ist möglich die Benachrichtigungen mithilfe eines eines Shell-Skript des Frameworks \texttt{Cron}\footnote{ Cron dient zur zeitbasierten Ausführung von definierten Aufgaben.} asynchron zu versenden. Der Inhalt kann Text oder HTML-basiert sein und in mehreren Sprachen hinterlegt werden.




\section{Bootstrap} \section{Bootstrap}
Um die Usability des Prototyps zu erhöhen, wird das Framework Bootstrap eingebunden. Um die Usability des Prototyps zu erhöhen, wird das Framework Bootstrap eingebunden.


Eine umfangreiche Website einheitlich zu gestalten ist oft sehr komplex und zeitaufwendig. Die Entwickler von Twitter haben deshalb an einem neuen Verwaltungswerkzeug gearbeitet, das mehrere Bibliotheken zusammenführen sollte (vgl. [Ott11]). Die Open-Source-Bibliothek, die auf GitHub abrufbar ist, wird seitdem von vielen Programmierern weiterentwickelt und ist somit stark gewachsen. Version 2.0 verfügt über die Fähigkeit Websites \textit{responsiv}\footnote{ Responsive Webseiten sind auf allen Endgeräten angepasst darstellbar.} auf verschiedenste mobile Endgeräte anzupassen (vgl. [Ott12]).
Eine umfangreiche Website einheitlich zu gestalten ist oft sehr komplex und zeitaufwendig. Die Entwickler von Twitter haben deshalb an einem neuen Verwaltungswerkzeug gearbeitet, das mehrere Bibliotheken zusammenführen sollte (vgl. [Ott11]). Die Open-Source-Bibliothek, die auf GitHub abrufbar ist, wird seitdem von vielen Programmierern weiterentwickelt und ist somit stark gewachsen. Version 2.0 verfügt über die Fähigkeit, Websites \textit{responsiv}\footnote{ Responsive Webseiten sind auf allen Endgeräten angepasst darstellbar.} auf verschiedenste mobile Endgeräte anzupassen (vgl. [Ott12]).


Das Bootstrap-Paket beinhaltet vorgefertigte Cascading Stylesheets, kurz CSS, die Farben, Schriftarten und viele weitere Stildefinitionen. Zudem befinden sich auch Erweiterungen des JavaScript-Frameworks jQuery in der Bibliothek, die weiterführende Funktionen beinhalten wie zum Beispiel Filter oder Dropdown-Menüs. Das Paket kann einfach eingebunden werden im head-tag einer HTML-Datei (vgl. Abbildung 2.3.). Das bedeutet, dass \textit{Media-Queries}\footnote{ Media-Qeries setzen statische Umbrüche um Layouts verschiedener Endgeräte anzupassen.} oder ähnliche Methoden nicht mehr nötig sind, nicht nur um eine Website mobilfähig zu machen, sondern auch kompatibel für die verschiedensten Browser (vgl. [Boo12]).
Das Bootstrap-Paket beinhaltet vorgefertigte Cascading Stylesheets, kurz CSS, die Farben, Schriftarten und viele weitere Stildefinitionen implizieren. Zudem befinden sich auch Erweiterungen des JavaScript-Frameworks jQuery in der Bibliothek, die weiterführende Funktionen beinhalten wie zum Beispiel Filter oder Dropdown-Menüs. Das Paket kann im head-tag einer HTML-Datei (vgl. Abbildung 2.3.) einfach eingebunden werden. Das bedeutet, dass \textit{Media-Queries}\footnote{ Media-Qeries setzen statische Umbrüche um Layouts verschiedener Endgeräte anzupassen.} oder ähnliche Methoden nicht mehr nötig sind - nicht nur um eine Website mobilfähig zu machen, sondern auch kompatibel für die verschiedensten Browser (vgl. [Boo12]).


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\includegraphics[width=1\textwidth]{figures/bootstrap-head-tag} \includegraphics[width=1\textwidth]{figures/bootstrap-head-tag}
\caption{Einbindung von Bootstrap in einer HTML-Datei.}
\caption{Einbindung von Bootstrap in einer HTML-Datei}
\hfill \hfill
\end{figure} \end{figure}


Durch das Einbinden von Bootstrap in einer HTML-Datei werden einige Styles bereits automatisch auf die darin vorkommenden Tags, wie Links und Überschriften, angewendet. Dies ist jedoch nur ein sehr kleiner Teil den die Bibliothek zur Verfügung stellt. Möchte man Bootstrap umfangreich nutzen so lassen sich die Stildefinitionen mit Klassen oder ID's in diverse HTML-Tags eintragen (vlg. Abbildung 2.4.).
Durch das Einbinden von Bootstrap in einer HTML-Datei werden einige Styles bereits automatisch auf die darin vorkommenden Tags, wie Links und Überschriften, angewendet. Dies ist jedoch nur ein sehr kleiner Teil, den die Bibliothek zur Verfügung stellt. Möchte man Bootstrap umfangreich nutzen, so lassen sich die Stildefinitionen mit Klassen oder ID's in diverse HTML-Tags eintragen (vlg. Abbildung 2.4.).


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \end{figure}


Möchte man bestimmte gestalterische Eigenschaften von Bootstrap überschreiben muss eine eigens verfasste CSS-Datei nach der Verlinkung von Bootstrap in die Website eingebunden werden. Der Parser liest die Datei von oben nach unten, Links nach Rechts. Liest dieser also zu erst die Bootstrap Bibliothek und speichert diese, so überschreiben die Styles die danach kommen, die bereits gelesenen Eingaben. Die Styles, die inline auf ein Tag angewendet werden sind somit die bestimmenden Eigenschaften.
Möchte man bestimmte gestalterische Eigenschaften von Bootstrap überschreiben, muss eine eigens verfasste CSS-Datei nach der Verlinkung von Bootstrap in die Website eingebunden werden. Der Parser liest die Datei von oben nach unten, links nach rechts. Liest dieser also zu erst die Bootstrap Bibliothek und speichert diese, so überschreiben die Styles, die danach kommen, die bereits gelesenen Eingaben. Die Styles, die inline auf ein Tag angewendet werden, sind somit die bestimmenden Eigenschaften.



+ 33
- 34
doc/bachelorarbeit_EstherKleinhenz/chapters/prototyp.tex View File

\chapter{Prototyp} \chapter{Prototyp}
\label{ch: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.
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 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 darauf aufbauend ein Produkt realisiert werden, das als Erweiterung in das Netzwerk der Hochschule integriert wird.


\section{Forschungsdesign} \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.
Dieses Kapitel veranschaulicht 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. Die Implementierung der Applikation kann nun auf Basis der Recherche durchgeführt werden. Dazu gehört das Testen verschiedener Bibliotheken und Erweiterungen, um das 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] \begin{figure}[!h]
\centering \centering


\section{Organisation} \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.
Um einen Einblick in den Aufbau eines Django-Projektes zu erlangen wird die Struktur 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-ons 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} \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.
Die Struktur der bereits bestehenden Datenbank im Django-Framework und die Erweiterungen desselben werden genauer erläutert. Zunächst wird auf die Ergänzung des bestehenden \texttt{UserModel} eingegangen, danach veranschaulicht der zweite Abschnitt das \texttt{PostModel} und abschlie"send werden die Zusammenhänge der Modelle dargestellt.


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \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
Alle Modelle werden als Django-Modelle deklariert um beim Kompilieren des Codes dem Compiler mitzuteilen, dass eine Integration stattfinden muss (vgl. [Dja18a]). Mit der Eingabe
\\ \\
\begin{addmargin}[0pt]{0pt} \begin{addmargin}[0pt]{0pt}
\noindent\hspace*{10mm}% \noindent\hspace*{10mm}%


\textbf{UserModel:} \textbf{UserModel:}
\begin{addmargin}[25pt]{0pt} \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]):
Hier ist das Authentifizierungssystem von Django mit einem \texttt{UserModel} bereits angelegt. Dieses muss für den Prototyp um das Feld \texttt{tags} erweitert werden, sodass ein Benutzer folgende Felder besitzt (vgl. [Fou18a]):
\begin{itemize} \begin{itemize}
\item username, fist\_name, last\_name, email, groups, user\_permissions, is\_staff, is\_active, is\_superuser, last\_login, date\_joined, tags \item username, fist\_name, last\_name, email, groups, user\_permissions, is\_staff, is\_active, is\_superuser, last\_login, date\_joined, tags
\end{itemize} \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]). \\
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.3.) 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, 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] \begin{figure}[!h]
\centering \centering


\textbf{PostModel:} \textbf{PostModel:}
\begin{addmargin}[25pt]{0pt} \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:
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} \begin{itemize}
\item author, title, text, created\_date, published\_date, tags \item author, title, text, created\_date, published\_date, tags
\end{itemize} \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.
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 wird deshalb als \texttt{TextField} deklariert. Erstellungsdatum und Publikation sind \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} \end{addmargin}


\textbf{Gesamtmodellierung:} \textbf{Gesamtmodellierung:}


\begin{addmargin}[25pt]{0pt} \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.
Die Abbildung 3.2. 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 angelegten CustomUser. Die im User vorkommenden \textit{booleschen Felder} werden im Kapitel \glqq Berechtigungen der User" genauer erörtert.
\end{addmargin} \end{addmargin}




\subsection{Berechtigungen der User} \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.
Im Allgemeinen verwendet man Berechtigungen, um Benutzern Zugang zu bestimmten Resourcen in einem Netzwerk einzuräumen. Au"serdem bestimmt eine Staffelung die Art des Zugangs, 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.
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, zur Hochschule ä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.
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. Dazu gehört das Hinzufügen von Tags, durch die damit verlinkten Beiträge das persönliche Dashboard befüllt wird. Dies soll verhindern, dass Informationen 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.
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 durchgeführt werden, jedoch sind der Gruppe noch keinerlei Rechte zugewiesen. Möchte man das ändern, kann man das von Django bereitgestellte Feld \texttt{User Permissions} im Admin-Backend unter \texttt{Users} finden, 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öglicha 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 das der Studierenden.




\section{Funktionen} \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. \\
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, Orangene wichtige Funktionen sind, aber nicht unbedingt notwendig, und Grüne kaum Relevanz haben. \\


\begin{figure}[!h] \begin{figure}[!h]
\centering \centering
\\ \\
\textbf{Einen neuen Artikel erstellen: } \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.
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.
Speichert der Benutzer den Artikel, so werden im Backend die Daten wie folgt verarbeitet. In der View \texttt{post\_new} wird zunächst geprüft, ob alle Eingaben valide sind. 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 danach explizit das von Django zur Verfügung gestellte \texttt{form.save\_m2m()} aufrufen zu können. Der 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.
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 ihn automatisiert beim Speichern der Tabelle als \texttt{AutoField} im Feld \texttt{Id} und identifiziert die \texttt{Id} 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: } \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.
In der Detailansicht eines Artikels ist es möglich, denselben zu entfernen. Die View \texttt{post\_remove} selektiert über den im Template mitgegebenen \texttt{Primary Key} das Objekt und speichert es in der Variable \texttt{post}. Der Post 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: } \textbf{Einen bereits vorhandenen Artikel bearbeiten: }
\hfill \hfill
\end{figure} \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.\\
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 sie 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] \begin{figure}[!h]
\centering \centering


\subsection{Artikel abonnieren} \subsection{Artikel abonnieren}


Das Abonnieren bestimmter Themengebiete ist eines der wichtigsten Funktionen im Prototyp um die eingepflegten Informationen zielgerichtet anzeigen zu können.
Das Abonnieren bestimmter Themengebiete ist eine 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. \\
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 den Artikel 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 gleiche Menge an Schlagwörtern 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] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \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.).
Im Prototyp findet man die Abonnement-Funktion unter dem Menüpunkt \texttt{Suche}. Hier erscheint ein zweigeteiltes 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 Layouts eine \textit{Tag-Cloud} \footnote{ Tag-Cloud ist eine Visualisierung eines Schlagwortverzeichnisses.}
, die alle Schlagwörter 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.
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] \begin{figure}[!h]
\centering \centering
\hfill \hfill
\end{figure} \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.
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 war.


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




\subsection{Filtern} \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.
Zur Unterstützung der Nutzbarkeit des Prototypen ist es wichtig, dass User intuitiv nach Tags suchen und sie 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.
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 eine Liste aller Beiträge, die den selektierten Tag 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.} desselben 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.
Der Prototyp bietet zudem die Möglichkeit direkt nach Tags zu suchen. Unter dem Menüpunkt \texttt{Suche} auf der linken Seite des geteilten Layouts befindet sich eine \textit{Tag-Cloud}. Darunter ist das Suchfeld, welches durch ein Formular im Template realisiert wird. Die Eingabe fragt jedoch nur Tags aus der Datenbank ab, die Daten werden nicht verändert, da hier lediglich ein \texttt{GET-Request} gesendet wird. 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 jeweils enthaltenen Tag dem Template übergeben werden.







Loading…
Cancel
Save