diff --git a/backend/RateMyCourse/settings.py b/backend/RateMyCourse/settings.py index 73873c8..4a8b0ad 100644 --- a/backend/RateMyCourse/settings.py +++ b/backend/RateMyCourse/settings.py @@ -134,3 +134,7 @@ USE_TZ = True # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' + +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, '../frontpage'), +] \ No newline at end of file diff --git a/backend/RateMyCourse/urls.py b/backend/RateMyCourse/urls.py index 8ac49dc..a3f6829 100644 --- a/backend/RateMyCourse/urls.py +++ b/backend/RateMyCourse/urls.py @@ -15,8 +15,21 @@ Including another URLconf """ from django.contrib import admin from django.urls import re_path,path,include +from django.conf.urls import url +from django.contrib.staticfiles.views import serve +from django.views.generic import RedirectView urlpatterns = [ + # / routes to index2.html + url(r'^$', serve, kwargs={'path': 'index2.html'}), + + # static files (*.css, *.js, *.jpg etc.) served on / + # (assuming Django uses /static/ and /media/ for static/media urls) + url(r'^(?!/?static/)(?!/?media/)(?P.*\..*)$', + RedirectView.as_view(url='/static/%(path)s', permanent=False)), + + # /universities/1/ Shows the page for a university. + # TODO: add pages for each rateable entity. path('admin/', admin.site.urls), re_path(r'^api/postings/', include(('postings.api.urls','postings'), namespace='api-postings')), ] diff --git a/backend/db.sqlite3 b/backend/db.sqlite3 index 31e0c11..f7ec704 100644 Binary files a/backend/db.sqlite3 and b/backend/db.sqlite3 differ diff --git a/backend/postings/admin.py b/backend/postings/admin.py index 05a8ce7..5961a97 100644 --- a/backend/postings/admin.py +++ b/backend/postings/admin.py @@ -1,6 +1,12 @@ from django.contrib import admin -from .models import UniversityReview +from .models import * # Register your models here. -admin.site.register(UniversityReview) \ No newline at end of file +admin.site.register(UniversityReview) +admin.site.register(Review) +admin.site.register(RateableEntity) +admin.site.register(ReviewHelpfulVote) +admin.site.register(University) +admin.site.register(Professor) +admin.site.register(Course) \ No newline at end of file diff --git a/backend/postings/api/serializers.py b/backend/postings/api/serializers.py index 0ac49dd..b8052b0 100644 --- a/backend/postings/api/serializers.py +++ b/backend/postings/api/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from postings.models import UniversityReview +from postings.models import * class UniversityReviewSerializer(serializers.ModelSerializer): @@ -16,4 +16,63 @@ class UniversityReviewSerializer(serializers.ModelSerializer): ] read_only_fields =[ 'pk', + 'username' + ] + +# Serializes the generic Review object. +class ReviewSerializer(serializers.ModelSerializer): + class Meta: + model = Review + fields = [ + 'pk', + 'rating', + 'title', + 'content', + 'rateable_entity', + 'created_date', + 'last_updated_date' + ] + read_only_fields = [ + 'pk', + 'created_date', + 'rateable_entity' + ] + +# Serializes Universities. +class UniversitySerializer(serializers.ModelSerializer): + class Meta: + model = University + fields = [ + 'pk', + 'name' + ] + read_only_fields = [ + 'pk' + ] + +# Serializes Courses. +class CourseSerializer(serializers.ModelSerializer): + class Meta: + model = Course + fields = [ + 'pk', + 'name', + 'taught_at_university', + 'professors' + ] + read_only_fields = [ + 'pk' + ] + +# Serializes Professors. +class ProfessorSerializer(serializers.ModelSerializer): + class Meta: + model = Professor + fields = [ + 'pk', + 'name', + 'universities' + ] + read_only_fields = [ + 'pk' ] \ No newline at end of file diff --git a/backend/postings/api/urls.py b/backend/postings/api/urls.py index d310315..1b6e317 100644 --- a/backend/postings/api/urls.py +++ b/backend/postings/api/urls.py @@ -1,11 +1,31 @@ -from .views import UniReviewRudView,UniReviewAPIView -from django.urls import re_path +from .views import * +from django.urls import path, re_path urlpatterns = [ + # /api/postings/reviews/ Lists all review objects. + path('reviews/', ReviewsView.as_view(), name='reviews'), + # /api/postings/reviews/1/ Returns data for one Review. + path('reviews/', ReviewView.as_view(), name='review'), + # /api/postings/universities/ Lists all university objects. + path('universities/', UniversitiesView.as_view(), name='universities'), + # /api/postings/universities/1/ Returns data for one University. + path('universities/', UniversityView.as_view(), name='university'), + + # /api/postings/courses/ Lists all course objects. + path('courses/', CoursesView.as_view(), name='courses'), + # /api/postings/courses/1/ Returns data for one Course. + path('courses/', CourseView.as_view(), name='course'), + + # /api/postings/professors/ Lists all professor objects. + path('professors/', ProfessorsView.as_view(), name='professors'), + # /api/postings/professors/1/ Returns data for one Professor. + path('professors/', ProfessorView.as_view(), name='professor'), + + # Deprecated re_path(r'^(?P\d+)/$', UniReviewRudView.as_view(), name='post-rud'), re_path(r'^$', UniReviewAPIView.as_view(), name='post-create') ] \ No newline at end of file diff --git a/backend/postings/api/views.py b/backend/postings/api/views.py index 8f22d4e..70cf3d6 100644 --- a/backend/postings/api/views.py +++ b/backend/postings/api/views.py @@ -1,6 +1,6 @@ from rest_framework import generics, mixins -from postings.models import UniversityReview -from .serializers import UniversityReviewSerializer +from postings.models import UniversityReview, Review +from .serializers import * from django.db.models import Q @@ -26,3 +26,43 @@ class UniReviewAPIView(mixins.CreateModelMixin, generics.ListAPIView): def post(self,request,*args,**kwargs): return self.create(request, *args, **kwargs) + +# The view for listing all generic Review objects. +class ReviewsView(mixins.CreateModelMixin, generics.ListAPIView): + queryset = Review.objects.all() + serializer_class = ReviewSerializer + +# View for an individual Review object. +class ReviewView(generics.RetrieveUpdateDestroyAPIView): + queryset = Review.objects.all() + serializer_class = ReviewSerializer + +# The view for listing all Universities. +class UniversitiesView(generics.ListAPIView): + serializer_class = UniversitySerializer + queryset = University.objects.all() + +# The view for an individual University. +class UniversityView(generics.RetrieveUpdateDestroyAPIView): + queryset = University.objects.all() + serializer_class = UniversitySerializer + +# The view for listing all Courses. +class CoursesView(generics.ListAPIView): + serializer_class = CourseSerializer + queryset = Course.objects.all() + +# The view for an individual Course. +class CourseView(generics.RetrieveUpdateDestroyAPIView): + queryset = Course.objects.all() + serializer_class = CourseSerializer + +# The view for listing all Professors. +class ProfessorsView(generics.ListAPIView): + queryset = Professor.objects.all() + serializer_class = ProfessorSerializer + +# The view for an individual Professor. +class ProfessorView(generics.RetrieveUpdateDestroyAPIView): + queryset = Professor.objects.all() + serializer_class = ProfessorSerializer \ No newline at end of file diff --git a/backend/postings/migrations/0004_auto_20180925_1941.py b/backend/postings/migrations/0004_auto_20180925_1941.py new file mode 100644 index 0000000..a3a0581 --- /dev/null +++ b/backend/postings/migrations/0004_auto_20180925_1941.py @@ -0,0 +1,81 @@ +# Generated by Django 2.1.1 on 2018-09-25 19:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('postings', '0003_universityreview_title'), + ] + + operations = [ + migrations.CreateModel( + name='RateableEntity', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=256)), + ], + ), + migrations.CreateModel( + name='Review', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rating', models.IntegerField(default=1)), + ('title', models.CharField(max_length=128)), + ('content', models.TextField()), + ('created_date', models.DateTimeField(auto_now_add=True)), + ('last_updated_date', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='ReviewHelpfulVote', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('helpful', models.BooleanField()), + ('review', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='postings.Review')), + ], + ), + migrations.CreateModel( + name='Course', + fields=[ + ('rateableentity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='postings.RateableEntity')), + ], + bases=('postings.rateableentity',), + ), + migrations.CreateModel( + name='Professor', + fields=[ + ('rateableentity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='postings.RateableEntity')), + ], + bases=('postings.rateableentity',), + ), + migrations.CreateModel( + name='University', + fields=[ + ('rateableentity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='postings.RateableEntity')), + ], + bases=('postings.rateableentity',), + ), + migrations.AddField( + model_name='review', + name='rateable_entity', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='postings.RateableEntity'), + ), + migrations.AddField( + model_name='professor', + name='university', + field=models.ManyToManyField(to='postings.University'), + ), + migrations.AddField( + model_name='course', + name='professors', + field=models.ManyToManyField(to='postings.Professor'), + ), + migrations.AddField( + model_name='course', + name='taught_at_university', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='postings.University'), + ), + ] diff --git a/backend/postings/migrations/0005_auto_20180925_2032.py b/backend/postings/migrations/0005_auto_20180925_2032.py new file mode 100644 index 0000000..94e10b8 --- /dev/null +++ b/backend/postings/migrations/0005_auto_20180925_2032.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.1 on 2018-09-25 20:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('postings', '0004_auto_20180925_1941'), + ] + + operations = [ + migrations.RenameField( + model_name='professor', + old_name='university', + new_name='universities', + ), + ] diff --git a/backend/postings/models.py b/backend/postings/models.py index b856ca1..b1d8bb8 100644 --- a/backend/postings/models.py +++ b/backend/postings/models.py @@ -35,7 +35,7 @@ class University(RateableEntity): # A RateableEntity for professors, who belong to one or more university. class Professor(RateableEntity): # The universities that this professor teaches or has taught at. - university = models.ManyToManyField('postings.University') + universities = models.ManyToManyField('postings.University') # A RateableEntity for courses, which belong to a university, and have one or more professors. class Course(RateableEntity):