-
Notifications
You must be signed in to change notification settings - Fork 0
Implementation Notes
Jump to:
The main contenders for web frameworks that we were considering were: Django and Flask. We chose Django because one of our team members, Alex Grant, had a significant amount of prior experience working with Django. The ease and stability of Django has served our app well.
Django is far too complex to explain in detail, but here is an overview of the main parts. If you are considering writing a web app with Django, we recommend you read through all of the topic guides. Anyway, the main components of the Django framework are:
- models
- URL files
- templates
- views
To understand the basics of how these components interact, let's pretend we want to make a webpage where we can input a list of your favorite books and display the list.
Once you have the html and CSS for the page, you need to create a view in views.py. Here is an example of a view.
def index(request):
return render(
request,
'tutor/index.html',
{"Subjects": list(models.Subject.objects.all())})
The view renders the web page with the correct html file (called a Template) with the Context (in this example the context is {"Subjects": list(models.Subject.objects.all())}). The context variables can be passed to the templates and called in the template using Django Template Language. DTL is very similar to Jinja2, so it may look familiar. For example, to call Subjects from the context, we would type {{ Subjects }}
in the html template in the place that we'd want to display the list of all subjects.
Once you have the template and the view set up, your page still won't load! That's because you need to add your desired address to the urls.py file. The URL page looks something like this:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<course_id>[0-9]+)/tutors/$', views.tutors, name='tutors'),
url(r'^startstop/$', views.startstop, name='startstop'),
url(r'^inbox/$', views.inbox, name='inbox'),
url(r'^about/$', views.about, name='about'),
]
When you decide what address you want for your books page, you can create a RegEx to represent the URL. Using a RegEx keeps the exact address from being static. Anyways, as you can see, each url() takes a view as input. This tells Django which exact view, and thereby which exact html file, you want Django to load for that particular URL. There's lots of fancy things we had to do with urlpatterns
that we won't get into.
So, now our page is loading! (assuming there's no bugs). But, how will we input data? For that, we will have to talk about models. Here is an example from our models.py page:
class Student(models.Model):
"""
Profile model for additional info about students
"""
user = models.OneToOneField(User, on_delete=models.CASCADE)
tutor = models.BooleanField(default=False)
tutoring_classes = models.ManyToManyField(
'Course',
blank=True,
related_name="tutors",
help_text="The courses that this student can tutor in.")
enrolled_classes = models.ManyToManyField(
'Course',
blank=True,
related_name="students",
help_text="The courses that this student is currently enrolled in.")
This code gives Subject the following attributes: user, tutor, tutoring_classes, and enrolled_classes. Each of the attributes specify what kind of data an admin can input into the database. Here, we have examples of booleans, character fields, and many-to-many relationships with other models (Course is another model). There are many other datatypes you can choose from. To input data into the model, the easiest way is to go through the admin page.
So, now that you inputted your favorite books, you can display the list in the template (the html file) using Django Template Language to reference the context that you created in the view, the view which is referenced in the urlpatterns
variable for the URL that you chose.
There are lots of other details, but that is the main gist of how Django works without getting too technical (hopefully).
When we decided that we wanted a forum-like part of our app, we initially decided to create it ourselves. We looked into different django-based forum apps to see what others had done, and there were a couple main contenders. The ones we seriously looked into were: Askbot, Spirit, and DjangoBB. DjangoBB had all of the features that we wanted from the forum, but it looked very early 2000's style and we didn't like that. Askbot had nice UI, but it was still in the beta phase of development. Spirit was our best option because it was fully developed and was nice to use. The main problem that we have encountered with Spirit is the complete and utter lack of documentation. Spirit is a very large application with many, many files, and navigating these files without documentation was pretty difficult even for making small modifications.
Additionally, while we liked the overall structure and formatting of Spirit and its styling in terms of layout of elements on the page, we still wanted to implement certain style changes such as color schemes, buttons, drop down menu styling, the incorporation of important links to our other app in the banner/header, etc. To preserve the original formatting/layout of spirit while also being able to make the changes we wanted, we made a "reed-base.css" file in the static directory (Spirit/spirit/core/static/spirit/stylesheets/reed-base.css), which imported/referenced the original spirit styling code (by means of: @import url("/static/spirit/stylesheets/styles.all.min.css");) so that we could keep what we liked about the interface while also making the styling changes we desired.
We may never know.
Originally, we were going to use Google Hangouts to handle the chat aspect of the project. This was going great until we found out that Google Hangouts is allegedly being phased out. We thought that this would interfere with our ability to provide a good chat service in the future. So, we chose Django Private Chat because it is in the alpha production stage and it is the only Django chat app that supports Python 3.
Django Private Chat is a python package, so all of the files live in our virtualenv. We have some of the Django Private Chat files in our repository, like dialogs.html. The files that we have overwrite the ones in the package, so this is how we have been able to customize the chat.