Commit e36c9d61 authored by Daniel W Bond's avatar Daniel W Bond
Browse files

Merge branch 'master' into bitesize

parents 7b829ef2 2e20337d
......@@ -122,7 +122,7 @@ Then run `python manage.py migrate` to execute that sql code and set up your dat
Finally, run `python manage.py createsuperuser` to create an admin account, using the same username and email as you'll access through CAS. This means your 'full' email address, for instance gmason@masonlive.gmu.edu. Your password will be handled through CAS, so you can just use 'password' here.
(If you accidentally skip this step, you can run `python manage.py shell` and edit your user from there.)
(If you accidentally skip this step, you can run `python manage.py shell` and edit your user from there. Selectyour user, and set .is_staff and .is_superuser to True, then save.)
## Loading in demo data
......@@ -142,100 +142,75 @@ Head over to localhost:8000 and see the site!
## Configuring the Social Media Applications
Social media authentication is provided through a package called [django-allauth](http://django-allauth.readthedocs.org/en/stable/installation.html). You can refer to those documentation pages for more information.
Social media authentication is provided through a package called [django-allauth](http://django-allauth.readthedocs.org/en/stable/installation.html). You can refer to those documentation pages for more information. Though in too many cases, the documenation is annoyingly sparse. The gulf between power of the package as shown through diving into the source and reading the documentation is vast.
What we're trying to accomplish with social media authentication is to verify users are linking to accounts they actually control. If we trusted users sufficiently to not type in gibberish or link to twitter.com/realDonaldTrump, we could provide a character field for each site.
Head over to localhost:8000/admin. Under 'Social Accounts', click on 'Social Applications'. Click 'Add social application' in the upper right hand corner. Start off by adding Facebook.
Head over to localhost:8000/admin. Under 'Social Accounts', click on 'Social Applications'. Click 'Add social application' in the upper right hand corner. We're going to start off by adding Facebook.
To fill in the name, id, key, and site for Facebook, and for all of the social media sites, you'll need to become a Developer for the site in question.
### Facebook
To fill in the name, id, key, and site for Facebook, (and for all of the social media sites), you'll need to become a Developer for the site in question.
Navigate to, for example, the Facebook web login [documentation page](https://developers.facebook.com/docs/facebook-login/web). On the toolbar across the top of the page, you'll see a tab called 'My Apps'. Hovering over it, you'll see the option to Register as a Developer. Click the link, accept the Facebook platform and privacy policies, and you'll be ready to go. Depending on how fleshed out your profile page is, you may be prompted for more information (such as a phone number).
On the page you'll be [redirected to](https://developers.facebook.com/quickstarts/), select the web app option. You'll be prompted to type the name of your new app. Go with something simple, like 'roomlist'. A dropdown will show an option to create a new app. Put Education as the category. Skip over 'namespace': that's used for specifically defining the app's name via Facebook's API. For the line labeled 'Site URL', type 'localhost:8000'. Hit 'next' and then click the link above the listed functionality that says 'Skip to Developer Dashboard'. (For the record, we're implementing the Login functionality.)
On the page you'll be [redirected to](https://developers.facebook.com/quickstarts/), select the website option. You'll be prompted to type the name of your new app. Because Facebook does not require apps to have globally unique names, go with something simple, like 'roomlist'. A dropdown will show an option to create a new app. Put Education as the category. Click on 'Create App ID'. If you see an option for 'namespace', skip over that for now: that's used for specifically defining the app's name via Facebook's API. For the line labeled 'Site URL', type 'localhost:8000'. Hit 'next' and then click the link on the section that lists functionality that says 'Skip to Developer Dashboard'. (For the record, we're implementing the Login functionality.)
After you click 'create app ID' and successfully complete a captcha, you'll be shown your app's dashboard. The two things you need on roomlist are right up at the top, the App ID and the App Secret.
You may be prompted to complete a captcha, and you'll then be shown your app's dashboard. The two things you need on roomlist are right up at the top, the App ID and the App Secret.
The user interface might be a bit different, particularly if you've done development with Facebook before, and some of these fields you may need to add after you've created the app. You may need to click 'Add Platform' from the Settings page of your app's Dashboard.
The user interface might be a bit different, particularly if you've done development with Facebook before, and some of these fields you may need to add after you've created the app. You may need to click 'Add Platform' from the Settings page of your app's Dashboard instead.
Back on the Django admin page, start filling in fields. App Name to Name, App ID to Client id, App Secret to Secret Key. The 'Sites' section is a security measure you can have in place to make sure that your app is only called from the urls you expect, and is what you put in for the 'Site URL' for the Facebook configuration.
Back on the Django admin page, start filling in fields. App Name to Name, App ID to Client id, App Secret to Secret Key. The 'Sites' section is a security measure to ensure your app is only called from the urls you expect, and is what you put in for the 'Site URL' for the Facebook configuration.
Under 'Available Sites', click the little green plus button and add a new site. The Domain Name will be '127.0.0.1' and the Display Name 'localhost'. By default, Django has already gone to the trouble of creating 'example.com' as a site. Move example.com back to available sites and make sure 127.0.0.1 is added to Chosen Sites.
By default, example.com is the first site. We'll add our site id, localhost. In settings.py, this is already accounted for; the default there is SITE_ID = 2.
Something you'll need to carefully specify is the callback (or redirect) url. This is where your user is sent once they have successfully authenticated with the outside social media site.
Let's add localhost to our Available sites, and then hit save.
Let's add localhost to our Available sites.
Something you'll need to carefully specify is the callback (or redirect) url. This is where your user is sent once they have successfully authenticated with the outside social media site.
Now, to Instagram.
### Instagram
Instagram actually asks you what you want to build and then will choose to give you access or not. Cross your fingers and let's begin the process.
Sign up as developer. Your website (localhost:8000) phone number (if you haven't already given it to Instagram, see above) and what you want to build with the API. 'Verify users are linking to social media accounts they in fact control.
Sign up as developer on Instagram's [developer site](https://www.instagram.com/developer). Click on 'register your application'. You'll be asked a couple things. For your website, use localhost:8000. If your Instagram account does not have a phone number, you'll be asked to provide it here. Finally, for what you want to build with the API, write something along the lines of 'Verify users are linking to social media accounts they in fact control.' Accept the terms and sign up.
Register Your Application.
Interestingly, you'll be redirected to the 'Register Your Application' page. Click on 'Register Your Application' once more. From the next page, 'Manage clients', click 'Register a New Client ID'. On this form, for your Application name, you can also be generic; this does not need to be globally unique. For the description, you can use the same signup description you used initially. All fields except privacy policy are required, so use 'SRCT' as the company name. The website url will be http://localhost:8000. The 'http://' is required. For the valid redirect URI, Instagram takes a different tact than the other oauth2 applications. You will need the full redirect path. Type http://localhost:8000/accounts/instagram/login/callback/. The trailing slash is for some reason important. Because you can support multiple URIs, then hit tab. Use a real contact email. The privacy policy is not required. Complete the captcha and hit 'Register'.
Manage clients.
Now add this information back into the Django admin. Create a new social application, and copy the client name to name, the client id to client id, and client secret to secret key. Make sure localhost is chosen as your site, and hit save.
Register new client ID.
### Twitter
Application name
Create a new social application, selecting Twitter as the provider.
Description
Head to the Twitter [developer's page](https://dev.twitter.com/). Sign in, and go to apps.twitter.com and click 'create a new app'. Twitter does not require you to register as a developer up front, there is merely an agreement at the bottom on the new app page. You will, however, be required to add and verify your phone number to your Twitter account profile before submitting any apps.
Company name(?) SRCT
You must enter an absolute URI that starts with http:// or https://
Submission error: all fields are required.
Website URL localhost:8000
Valid redirect urls: localhost:8000 (tab after to make it a link)
http://localhost:8000/accounts/instagram/login/callback/
contact email
Captcha
Unlike the previous two sites, your app name must actually be globally unique. Pick, for example, 'roomlist-1234'. Next, your description will actually be shown to users when they sign in, so make sure it's reasonably coherent. Write something like 'verify your twitter account for roomlist'. For the website, use http://127.0.0.1:8000/. Use the same address for the callback, http://127.0.0.1:8000/. Agree to the developer terms, and click 'create your application'.
Next, to Twitter.
Next, by default, Twitter gives you more permissions than you actually need. On the app's page. click to the 'Permissions' tab. As we do not need to write to the users' Twitter account pages, select 'Read Only', and update your settings.
Must actually be unique
Now, click to the tab 'Keys and Access Tokens', and copy the 'Consumer Key' to Client ID on your new social application, and the 'Consumer Secret' to Secret Key. Make sure the name is the unique one you gave your app. Set localhost as your Site, and click Save.
Use http://127.0.0.1:8000/
### Google
Permissions: Read only
Google's auth setup process is unquestionably the most confusing of the bunch, and yet we proceed, despite the ceiling of students who will link their Google+ page being approximately four.
Finally, to Google.
Google's auth setup process is unquestionably the most confusing of the bunch, and yet we proceed, despite the number of students who will link their Google+ page will likely be no more than four.
Project name-- google gives you the project name
Verify you have your phone number associated with your Google account, and then head to Google's [developer page](https://developers.google.com/). On that page, click 'Web'. Under the column titled 'Develop', click 'Sign In', and then click 'Get Started'.
enable and manage apis
The first step, will link you to the Google Developer's console. Click that link, then, intuitively (/s) click 'Select a Project' in the navbar, and then 'Create a Project' in the dropdown.
google+
Type 'roomlist' in the project name field. Google will give you a globally unique project name underneath the field. Agree to the terms, and click 'create'.
credentials
add credentials
oauth2 client id
web application
name
authorized javascript origins
http://127.0.0.1:8000
authorized redirect urls
with trailing slash localhost
you'll see them in a popup...
roomlist or generated roomlist?
Project name-- google gives you the project name
project consent screen
email address
product name shown to users
Go now to 'enable and manage APIs'. On the new screen under 'social APIs', click Google+ API. Click 'enable API', and then on the sidebar click 'credentials'. Then click 'add credentials', and 'oauth2 client id' under the dropdown. You will be asked to first configure a user consent screen (similar to the description we wrote for the Twitter client's authentication page). The only required field is your project name. Save, and then on the screen 'create client ID', click 'web application'. Name your project roomlist (this is only for your piece of mind, the actual name you'll use for Django is still the one Google generated for you), the authorized javascript origin is http://127.0.0.1:8000, without the trailing slash. For the authorized redirect url, type the full path like with Instagram, but inexplicably use 'localhost': http://localhost:8000/accounts/google/login/callback/, and *with* the trailing slash. Click 'Create'.
domain verification
Copy the Client ID and Client Secret from the popup window that you'll then see into the Django social app's Client ID and Secret Key, respectively. Unless you delete the preceeding and trailing space when you copy the hashes, you will be sad because your string will be wrong.
your site must be registered on the search console
If you've forgotten the name with the number, back on Google's page it's in the navbar, if you click on the more human-readable app's name.
watch out for trailing spaces!!
Add localhost as the site, click save, and throw a party, because thank goodness, you're finally all set.
### Notes on Cacheing
......
......@@ -215,6 +215,24 @@ class Student(TimeStampedModel):
def get_flag_count(self):
my_flag_num = Confirmation.objects.filter(student=self, lives_there=False).count()
return my_flag_num
def get_first_name_or_uname(self):
if not(self.user.get_short_name()):
return self.user.username
else:
return self.user.get_short_name()
def get_last_name_or_uname(self):
if not(self.user.last_name):
return self.user.username
else:
return self.user.last_name
def get_full_name_or_uname(self):
if not(self.user.get_full_name()):
return self.user.username
else:
return self.user.get_full_name()
class Meta:
ordering = ['user']
......@@ -224,7 +242,7 @@ class Student(TimeStampedModel):
def __unicode__(self):
return unicode(self.user.username)
# def save(self, *args, **kwargs):
#print('we be savin\'!')
#from django.db.models.signals import pre_save, post_save
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT RoomList | Flag {{ student.user.get_full_name }} {% endblock %}
{% block title %} SRCT RoomList | Flag {{ student.get_full_name_or_uname }} {% endblock %}
{% block message_queue %}
{% endblock %}
......@@ -14,11 +14,7 @@
<p class="lead text-center">
<i class="fa fa-flag fa-lg"></i>
<strong>
{% if not student.user.get_full_name %}
Someone
{% else %}
{{ student.user.get_full_name }}
{% endif %}
{{ student.get_full_name_or_uname }}
</strong>
<em>is in the wrong room!</em>
</div>
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT RoomList | Remove Flag {{ confirmation.student.user.get_full_name }} {% endblock %}
{% block title %} SRCT RoomList | Remove Flag {{ confirmation.student.get_full_name_or_uname }} {% endblock %}
{% block message_queue %}
{% endblock %}
......@@ -15,11 +15,7 @@
<i class="fa fa-flag fa-lg"></i>
Maybe
<strong>
{% if not confirmation.student.user.get_full_name %}
Someone
{% else %}
{{ confirmation.student.user.get_full_name }}
{% endif %}
{{ confirmation.student.get_first_name_or_uname }}
</strong>
<em>is in the correct room after all...</em>
</div>
......
......@@ -6,15 +6,15 @@
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-2 col-md-offset-1 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_full_name_or_uname }} profile picture">
</div>
<div class="col-md-6 text-center">
<h1><strong>{{ student.user.get_full_name }}</strong></h1>
<h1><strong>{{ student.get_full_name_or_uname }}</strong></h1>
{% if shares %}
<p class="lead"><strong>
{% if student.room == None %}
{{ student.user.first_name }} hasn't set their room yet.
{{ student.get_first_name_or_uname }} hasn't set their room yet.
{% else %}
<a href="{{ student.room.get_absolute_url }}">{{ student.room }}</a>
{% if same_floor %}
......
......@@ -27,8 +27,8 @@
<div class="row">
{% for student in building.list %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
{% if student.get_flag_count > 4 %}
<p><em>* a number of other floormates say this info is incorrect</em></p>
{% endif %}
......@@ -53,8 +53,8 @@
<div class="row">
{% for student in building.list %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
{% if student.get_flag_count > 4 %}
<p><em>* a number of other floormates say this info is incorrect</em></p>
{% endif %}
......@@ -79,8 +79,8 @@
<div class="row">
{% for student in building.list %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
{% if student.get_flag_count > 4 %}
<p><em>* a number of other floormates say this info is incorrect</em></p>
{% endif %}
......@@ -101,8 +101,8 @@
<div class="col-md-12">
{% for student in location_hidden %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
</div>
{% endfor %}
</div>
......
{{ object.user.username }}
{{ object.user.get_full_name }}
{{ object.user.get_full_name_or_uname }}
......@@ -45,7 +45,7 @@ SRCT Roomlist &bull; Search Students
<h4>{{ result.object.user.username }}</h4>
</td>
<td>
<a href="{{ result.object.get_absolute_url }}"><h4><strong>{{ result.object.user.get_full_name }}</strong></h4></a>
<a href="{{ result.object.get_absolute_url }}"><h4><strong>{{ result.object.get_full_name_or_uname }}</strong></h4></a>
</td>
<td>
{% if result.object.major %}
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT Roomlist | {{ student.user.first_name }} {{ student.user.last_name }} {% endblock %}
{% block title %} SRCT Roomlist | {{ student.get_full_name_or_uname }} {% endblock %}
{% block messsage_queue %}
{% endblock %}
......@@ -12,8 +12,8 @@
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-8 col-md-offset-2 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} Gravatar picture">
<h1>{{ student.user.first_name }} {{ student.user.last_name }}, {{ student.user.username }}</h1>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} Gravatar picture">
<h1>{{ student.get_full_name_or_uname }} , {{ student.user.username }}</h1>
</div>
</div>
</div>
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT Roomlist | Student | Update {% endblock %}
{% block title %} SRCT Roomlist | Student | {{ request.user.student.get_full_name_or_uname }} | Update {% endblock %}
{% block message_queue %}
{% endblock %}
......@@ -21,7 +21,7 @@
<div class="row">
<div class="col-md-12 text-center">
<h2><strong>Welcome, {{ request.user.first_name }}!</strong></h2>
<h2><strong>Welcome, {{ request.user.student.get_first_name_or_uname }}!</strong></h2>
</div>
</div>
......
......@@ -23,7 +23,7 @@
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">Now let's verify your major. This lets others find you and others with their same major, which, for example, makes it easier to form study groups.</p>
<p class="text-center">Now let's verify your major, {{ request.user.student.get_first_name_or_uname }}. This lets others find you and others with their same major, which, for example, makes it easier to form study groups.</p>
<p class="text-center">Then, add what year you expect you'll graduate.</p>
</div>
</div>
......
......@@ -25,7 +25,7 @@
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">Great! Now to your housing information and settings. Here, you'll select which room you live in, and then choose who you want to be able to see that information.</p>
<p class="text-center">Great, {{ request.user.student.get_first_name_or_uname }}! Now to your housing information and settings. Here, you'll select which room you live in, and then choose who you want to be able to see that information.</p>
<p class="text-center"><strong>By default, your privacy is set to 'Floor'.</strong> That means only other students living on your floor can see your room.</p>
<p class="text-center">You can choose to set your privacy to 'Building', which will make your room visible to everyone living in your building, or to 'Campus', where it will be visible to anyone with a current Mason username and password.</p>
</div>
......
......@@ -25,6 +25,7 @@
<div class="col-md-8 col-md-offset-2">
<p class="text-center">We're not trying to recreate Facebook here. On this final step, you can point people to a variety of your social media accounts from your user page.</p>
<p class="text-center">You'll be asked to sign in, but that's just to verify the account actually belongs to you. With the exception of your choice to use your Facebook profile picture as your profile picture here, we don't use any information on these third-party sites.</p>
<p class="text-center">We'll only show these links to people who can also see your room.</p>
</div>
</div>
......
......@@ -25,8 +25,8 @@
<div class="row">
{% for student in students %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
<h5><a href="{{ student.major.get_absolute_url }}"><em>{{ student.major.name }}</em></a></h5>
<h5><a href="{{ student.room.get_absolute_url }}">{{ student.room }}</a></h5>
{% if student.get_flag_count %}
......
......@@ -27,8 +27,8 @@
<div class="row">
{% for student in students %}
<div class="col-sm-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.user.first_name }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.first_name }} {{ student.user.last_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
<h5><a href="{{ student.major.get_absolute_url }}"><em>{{ student.major.name }}</em></a></h5>
{% if student.get_flag_count > 4 %}
<p><em>* a number of other floormates say this info is incorrect</em></p>
......
......@@ -4,7 +4,7 @@
{% load cache %}
{% load gravatar %}
<h2>Welcome Back {{ request.user.first_name }}!</h2>
<h2>Welcome Back {{ me.get_first_name_or_uname }}!</h2>
<legend></legend>
{% if not me.room %}
......@@ -21,18 +21,20 @@
{% endif %}
<div class="row">
{% for student in roomies %}
<div class="col-md-3 text-center">
<a href="{{ student.get_absolute_url }}"><img class="img-circle img-responsive center center-block" src="{% gravatar_url student.user.email 100 %}" alt="{{ student.user.first_name }} Gravatar picture"></img></a>
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.get_full_name }}</strong></a></h4>
<h5><a href="{{ student.major.get_absolute_url }}"><em>{{ student.major }}</em></a></h5>
</div>
<div class="col-md-3 text-center">
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture"></img>
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
<h5><a href="{{ student.major.get_absolute_url }}"><em>{{ student.major }}</em></a></h5>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
<br />
<div class="row">
{% endif %}
{% empty %}
<h4>There are no other students registered in your room right now.</h4>
<div class="col-md-12">
<h4>There are no other students registered in your room right now.</h4>
</div>
{% endfor %}
</div>
{% endcache %}
......@@ -45,8 +47,8 @@
<div class="row">
{% for student in floories %}
<div class="col-md-3 text-center">
<a href="{{ student.get_absolute_url }}"><img class="img-circle img-responsive center center-block" src="{% gravatar_url student.user.email 100 %}" alt="{{ student.user.first_name }} Gravatar picture"></a>
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.user.get_full_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
<h5><a href="{{ student.major.get_absolute_url }}"><em>{{ student.major }}</em></a></h5>
<h5><a href="{{ student.room.get_absolute_url }}">{{ student.room }}</h5></a>
</div>
......@@ -56,7 +58,9 @@
<div class="row">
{% endif %}
{% empty %}
<h4>There are no other students registered on your floor right now.</h4>
<div class="col-md-12">
<h4>There are no other students registered on your floor right now.</h4>
</div>
{% endfor %}
</div>
{% endcache %}
......@@ -73,8 +77,8 @@
<div class="row">
{% for student in majormates %}
<div class="col-md-3 text-center">
<a href="{{ student.get_absolute_url }}"><img class="img-circle img-responsive center center-block" src="{% gravatar_url student.user.email 100 %}" alt="{{ student.user.first_name }} Gravatar picture"></a>
<h4><a href="{{ student.get_full_name }}"><strong>{{ student.user.get_full_name }}</strong></a></h4>
<img class="img-circle img-responsive center center-block" src="{{ student.profile_image_url }}" alt="{{ student.get_first_name_or_uname }} profile picture">
<h4><a href="{{ student.get_absolute_url }}"><strong>{{ student.get_full_name_or_uname }}</strong></a></h4>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
......@@ -82,7 +86,9 @@
<div class="row">
{% endif %}
{% empty %}
<h4>There are no other students registered in your major right now.</h4>
<div class="col-md-12">
<h4>There are no other students registered in your major right now.</h4>
</div>
{% endfor %}
</div>
{% endcache %}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment