diff --git a/pyconbalkan/conference/__init__.py b/pyconbalkan/conference/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/admin.py b/pyconbalkan/conference/admin.py new file mode 100644 index 00000000..9cb49893 --- /dev/null +++ b/pyconbalkan/conference/admin.py @@ -0,0 +1,17 @@ +from django.contrib import admin + +from pyconbalkan.conference.models import Conference, CountDown + + +class ConferenceAdmin(admin.ModelAdmin): + class Meta: + model = Conference + + +class CountDownAdmin(admin.ModelAdmin): + class Meta: + model = CountDown + + +admin.site.register(Conference, ConferenceAdmin) +admin.site.register(CountDown, CountDownAdmin) diff --git a/pyconbalkan/conference/api_urls.py b/pyconbalkan/conference/api_urls.py new file mode 100644 index 00000000..8d3e84e8 --- /dev/null +++ b/pyconbalkan/conference/api_urls.py @@ -0,0 +1,6 @@ +from rest_framework import routers + +from pyconbalkan.conference.views import ConferenceViewSet + +router = routers.DefaultRouter() +router.register(r'conference', ConferenceViewSet) \ No newline at end of file diff --git a/pyconbalkan/conference/apps.py b/pyconbalkan/conference/apps.py new file mode 100644 index 00000000..cd92fc5c --- /dev/null +++ b/pyconbalkan/conference/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ConferenceConfig(AppConfig): + name = 'conference' diff --git a/pyconbalkan/conference/migrations/0001_initial.py b/pyconbalkan/conference/migrations/0001_initial.py new file mode 100644 index 00000000..bf02991d --- /dev/null +++ b/pyconbalkan/conference/migrations/0001_initial.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.11 on 2018-04-26 21:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django_countries.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Conference', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=False)), + ('event', models.CharField(blank=True, max_length=100, null=True)), + ('name', models.CharField(blank=True, max_length=100, null=True)), + ('year', models.PositiveIntegerField()), + ('number', models.PositiveIntegerField()), + ('city', models.CharField(blank=True, max_length=200, null=True)), + ('country', django_countries.fields.CountryField(blank=True, max_length=2, null=True)), + ('address', models.TextField(blank=True, null=True)), + ('from_date', models.DateField(blank=True, null=True)), + ('to_date', models.DateField(blank=True, null=True)), + ('max_attendees', models.PositiveIntegerField(blank=True, null=True)), + ('type', models.IntegerField(choices=[(0, 'International'), (1, 'National')])), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='CountDown', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=False)), + ('title', models.CharField(blank=True, max_length=100, null=True)), + ('count_down', models.DateTimeField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/pyconbalkan/conference/migrations/__init__.py b/pyconbalkan/conference/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/models.py b/pyconbalkan/conference/models.py new file mode 100644 index 00000000..fb3e69cc --- /dev/null +++ b/pyconbalkan/conference/models.py @@ -0,0 +1,37 @@ +from django.db import models +from django_countries.fields import CountryField + +from pyconbalkan.core.models import SingleActiveModel + + +class Conference(SingleActiveModel): + INTERNATIONAL = 0 + NATIONAL = 1 + CONF_TYPE = ( + (INTERNATIONAL, 'International'), + (NATIONAL, 'National'), + ) + + event = models.CharField(null=True, blank=True, max_length=100) + name = models.CharField(null=True, blank=True, max_length=100) + year = models.PositiveIntegerField() + number = models.PositiveIntegerField() + city = models.CharField(null=True, blank=True, max_length=200) + country = CountryField(null=True, blank=True) + address = models.TextField(null=True, blank=True) + from_date = models.DateField(null=True, blank=True) + to_date = models.DateField(null=True, blank=True) + max_attendees = models.PositiveIntegerField(null=True, blank=True) + type = models.IntegerField(choices=CONF_TYPE) + + + def __str__(self): + return '{} {} {}'.format(self.event, self.name, self.year) + + +class CountDown(SingleActiveModel): + title = models.CharField(null=True, blank=True, max_length=100) + count_down = models.DateTimeField(null=True, blank=True) + + def __str__(self): + return self.title \ No newline at end of file diff --git a/pyconbalkan/conference/serializers.py b/pyconbalkan/conference/serializers.py new file mode 100644 index 00000000..5e8a3ed8 --- /dev/null +++ b/pyconbalkan/conference/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from pyconbalkan.conference.models import Conference + + +class ConferenceSerializer(serializers.ModelSerializer): + class Meta: + model = Conference + fields = '__all__' diff --git a/pyconbalkan/conference/templates/index.html b/pyconbalkan/conference/templates/index.html new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/tests.py b/pyconbalkan/conference/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/pyconbalkan/conference/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pyconbalkan/conference/views.py b/pyconbalkan/conference/views.py new file mode 100644 index 00000000..fbfda053 --- /dev/null +++ b/pyconbalkan/conference/views.py @@ -0,0 +1,9 @@ +from rest_framework import viewsets + +from pyconbalkan.conference.models import Conference +from pyconbalkan.conference.serializers import ConferenceSerializer + + +class ConferenceViewSet(viewsets.ModelViewSet): + queryset = Conference.objects.all() + serializer_class = ConferenceSerializer diff --git a/pyconbalkan/core/admin.py b/pyconbalkan/core/admin.py index 26f78a8e..c42474ae 100644 --- a/pyconbalkan/core/admin.py +++ b/pyconbalkan/core/admin.py @@ -3,3 +3,4 @@ class CoreConfig(AppConfig): name = 'core' + diff --git a/pyconbalkan/core/api_urls.py b/pyconbalkan/core/api_urls.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/core/models.py b/pyconbalkan/core/models.py index 71a83623..98103407 100644 --- a/pyconbalkan/core/models.py +++ b/pyconbalkan/core/models.py @@ -1,3 +1,21 @@ from django.db import models -# Create your models here. + +class SingleActiveModel(models.Model): + active = models.BooleanField(default=False) + + class Meta: + abstract = True + + def save(self, *args, **kwargs): + if self.active: + # select all other active items + qs = type(self).objects.filter(active=True) + # except self (if self already exists) + if self.pk: + qs = qs.exclude(pk=self.pk) + # and deactive them + qs.update(active=False) + + super(SingleActiveModel, self).save(*args, **kwargs) + diff --git a/pyconbalkan/core/routers.py b/pyconbalkan/core/routers.py new file mode 100644 index 00000000..a0924cdc --- /dev/null +++ b/pyconbalkan/core/routers.py @@ -0,0 +1,15 @@ +from rest_framework import routers + + +class DefaultRouter(routers.DefaultRouter): + """ + Extends `DefaultRouter` class to add a method for extending url routes from another router. + """ + def extend(self, router): + """ + Extend the routes with url routes of the passed in router. + + Args: + router: SimpleRouter instance containing route definitions. + """ + self.registry.extend(router.registry) \ No newline at end of file diff --git a/pyconbalkan/core/static/css/style.css b/pyconbalkan/core/static/css/style.css new file mode 100644 index 00000000..d9bf9cd2 --- /dev/null +++ b/pyconbalkan/core/static/css/style.css @@ -0,0 +1,246 @@ +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 900; + src: local('Montserrat Black'), local('Montserrat-Black'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_epG3gnD_g.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + + +body { + font-family: 'Montserrat', sans-serif; + font-weight: 400; + max-width: 100%; + margin: 0; + /* The image used */ + /* Full height */ + height: 100%; + /* Center and scale the image nicely */ + background: url('/static/img/background.jpg') no-repeat no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.navbar-brand img { + height: auto; +} + +.round { + border-radius: 24px; +} + + +.btn-light { + background: transparent; + color: white; + border-color: transparent; +} + +.btn-light:hover, +.btn-light:focus, +.btn-light:active +{ + color: black; + border-color: #F3D66C; + outline: none !important; + box-shadow: none !important; + background: #F3D66C; +} + +.font900 { + font-family: 'Montserrat', sans-serif; + font-weight: 900; +} + +.one { + margin-bottom: -12px; + font-size: 4.5rem; +} + +h2 { + max-height: inherit; + letter-spacing: 0.01em; +} + +h3 { + font-size: 2rem; + margin-top: 5px; + margin-left: 2px; + max-height: inherit; + letter-spacing: 0.05em; +} + + +.row { + margin-left: 20px; + margin-right: 0px; +} + +hr { + width: 12%; + position: absolute; + border-width: 2px; + background: #22A4D9; +} + +.details { + margin-top: 50px; + margin-right: 10px; +} + +.font-yellow { + color: #F3D66C; +} + +.font-blue { + color: #22A4D9; +} + +.fa-calendar-alt, .fa-users, .fa-globe{ + color: #22A4D9; + display: inline-block; + width: 20px; +} + +.btn-primary { + background: #22A4D9; + border-color: #22A4D9; + color: white; + width: 200px; +} + +.sn-icons { + margin-top: 30px; + margin-right: 30px; + +} + +#days { + font-size: 3rem; + border: 10px solid white; + border-radius: 20px; + background-color: white; +} + +#days-text { + padding-left: 10px; + font-size: 3rem; +} + +.hms { + font-size: 1.8rem; +} + +.hms-text { + font-size: 0.6rem; + color: white; +} + +.countdown-timer{ + margin-top: 30px; +} + +ul.countdown { + list-style: none; + display: inline; + text-align: center; + padding-left: 15px; +} + +ul.countdown li { + display: inline-block; + vertical-align: -12px; + margin-right: 5px; +} + +ul.countdown li div { + margin-top: -5px; +} + +.btn-secondary { + background: #F3D66C; + border-color: #F3D66C; + color: black; +} + +.btn-secondary:hover, +.btn-secondary:focus, +.btn-secondary:active +{ + color: black; + border-color: #F3D66C; + outline: none !important; + box-shadow: none !important; + background: #F3D66C; +} + +.moveDown { + margin-top: 50px; +} + +#btnBuyNow { + width: 120px; +} + +.card { + background: transparent; + border: none; + margin-right: 0 !important; +} + +.card .row { + margin-left: 0 !important; +} + + +.card img { + width: 80px; + float: left; +} + +.card ul { + list-style: none; + vertical-align: middle; + color: white; + padding: 0; +} + +.card li:first-child { + font-size: 1rem; + display: grid; + padding-left: 10px; +} + +.card li { + font-size: 0.8rem; + display: grid; + padding-left: 10px; + margin-top: 5px; +} + +.card hr { + display: inline; + margin: 0 0 0 10px; +} + +.col-sm { + padding: 0; +} + +#seeMore { + width: 150px; +} + +#attend { + width: auto; +} \ No newline at end of file diff --git a/pyconbalkan/core/static/img/background.jpg b/pyconbalkan/core/static/img/background.jpg new file mode 100644 index 00000000..608a618f Binary files /dev/null and b/pyconbalkan/core/static/img/background.jpg differ diff --git a/pyconbalkan/core/static/img/favicon-16x16.png b/pyconbalkan/core/static/img/favicon-16x16.png new file mode 100644 index 00000000..401ccd11 Binary files /dev/null and b/pyconbalkan/core/static/img/favicon-16x16.png differ diff --git a/pyconbalkan/core/static/img/favicon-32x32.png b/pyconbalkan/core/static/img/favicon-32x32.png new file mode 100644 index 00000000..47a4d3f8 Binary files /dev/null and b/pyconbalkan/core/static/img/favicon-32x32.png differ diff --git a/pyconbalkan/core/static/img/logo.jpg b/pyconbalkan/core/static/img/logo.jpg new file mode 100644 index 00000000..86edc8c2 Binary files /dev/null and b/pyconbalkan/core/static/img/logo.jpg differ diff --git a/pyconbalkan/core/static/js/timer.js b/pyconbalkan/core/static/js/timer.js new file mode 100644 index 00000000..8f0f69e7 --- /dev/null +++ b/pyconbalkan/core/static/js/timer.js @@ -0,0 +1,30 @@ +// Set the date we're counting down to +var countDownDate = new Date("May 15, 2018 00:00:01").getTime(); + +// Update the count down every 1 second +var x = setInterval(function() { + + // Get todays date and time + var now = new Date().getTime(); + + // Find the distance between now an the count down date + var distance = countDownDate - now; + + // Time calculations for days, hours, minutes and seconds + var days = Math.floor(distance / (1000 * 60 * 60 * 24)); + var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((distance % (1000 * 60)) / 1000); + + // Output the result in an element with id="demo" + document.getElementById("days").innerHTML = days; + document.getElementById("hours").innerHTML = hours + ":"; + document.getElementById("minutes").innerHTML = minutes + ":"; + document.getElementById("seconds").innerHTML = seconds; + + // If the count down is over, write some text + if (distance < 0) { + clearInterval(x); + document.getElementById("demo").innerHTML = "EXPIRED"; + } +}, 1000); \ No newline at end of file diff --git a/pyconbalkan/core/templates/home.html b/pyconbalkan/core/templates/home.html new file mode 100644 index 00000000..a700f6c6 --- /dev/null +++ b/pyconbalkan/core/templates/home.html @@ -0,0 +1,198 @@ +{% load static %} + + + + + + PyCon Balkan 2018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + +
+ + + + +
+
+ {% if conference %} +

{{ conference.event }}

+

{{ conference.name }}

+

{{ conference.city }} {{ conference.year }}

+ {% endif %} +
+
+ {% if conference %} +
+

#{{ conference.number }}

+

{{ conference.address }}

+
+

{{ conference.from_date }} - {{ conference.to_date }}

+

{{ conference.max_attendees }} attendees

+

{{ conference.get_type_display }}

+
+{#
#} +{# JOIN US#} +{#
#} +{#
#} +{# #} +{# #} +{# #} +{#
#} +
+ {% endif %} +
+ + + + + + +
+ {% if count_down %} +

{{ count_down.title }}

+
+ + Days +
    +
  • + +
    hours
    +
  • +
  • + +
    minutes
    +
  • +
  • + +
    sec
    +
  • +
+
+ +{#
#} +{# Buy Now#} +{#
#} + {% endif %} + +
+

Speakers

+
+ + {% if speakers %} +
+
+
+ {% for speaker in speakers %} +
+ +
    +
  • {{ speaker.name }}
  • +
    +
  • {{ speaker.job }}
  • +
+
+ {% endfor %} +
+
+
+ {% else %} +
+ COMING SOON +
+ {% endif %} + + +{#
#} +{# See More#} +{# Attend#} +{#
#} +
+ + + + +
+ + + + + + + + diff --git a/pyconbalkan/core/templates/index.html b/pyconbalkan/core/templates/index.html deleted file mode 100644 index 5c9b3dd5..00000000 --- a/pyconbalkan/core/templates/index.html +++ /dev/null @@ -1,37 +0,0 @@ -{% load static %} - - - - - - - PyCon Balkan 2018 - - - - - - -
- COMING SOON -
- - - \ No newline at end of file diff --git a/pyconbalkan/core/views.py b/pyconbalkan/core/views.py index ff509c5f..a42c158a 100644 --- a/pyconbalkan/core/views.py +++ b/pyconbalkan/core/views.py @@ -1,5 +1,18 @@ from django.shortcuts import render +from pyconbalkan.conference.models import Conference, CountDown +from pyconbalkan.speaker.models import Speaker, SpeakerPhoto + def home(request): - return render(request, 'index.html') + conference = Conference.objects.filter(active=True) + count_down = CountDown.objects.filter(active=True) + speakers = Speaker.objects.filter(active=True) + context = { + 'speakers': speakers, + 'conference': conference.first() if conference else None, + 'count_down': count_down.first() if count_down else None, + } + return render(request, 'home.html', context) + + diff --git a/pyconbalkan/settings.py b/pyconbalkan/settings.py index b3b60282..e2d93d08 100644 --- a/pyconbalkan/settings.py +++ b/pyconbalkan/settings.py @@ -39,7 +39,13 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + # apps 'pyconbalkan.core', + 'pyconbalkan.conference', + 'pyconbalkan.speaker', + # others + 'rest_framework', + 'django_countries', ] MIDDLEWARE = [ @@ -121,4 +127,17 @@ STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') -PDF_ROOT = os.path.join(BASE_DIR, 'pyconbalkan/core/static/pdf/') \ No newline at end of file +PDF_ROOT = os.path.join(BASE_DIR, 'pyconbalkan/core/static/pdf/') +MEDIA_ROOT = os.path.join(BASE_DIR, 'pyconbalkan/core/') +MEDIA_URL = '/img/' + + +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' + ], + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', + 'PAGE_SIZE': 10 +} diff --git a/pyconbalkan/speaker/__init__.py b/pyconbalkan/speaker/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/speaker/admin.py b/pyconbalkan/speaker/admin.py new file mode 100644 index 00000000..1141726b --- /dev/null +++ b/pyconbalkan/speaker/admin.py @@ -0,0 +1,14 @@ +from django.contrib import admin + +from pyconbalkan.speaker.models import SpeakerPhoto, Speaker + + +class SpeakerImageInline(admin.TabularInline): + model = SpeakerPhoto + + +class SpeakerAdmin(admin.ModelAdmin): + inlines = [SpeakerImageInline] + + +admin.site.register(Speaker, SpeakerAdmin) diff --git a/pyconbalkan/speaker/api_urls.py b/pyconbalkan/speaker/api_urls.py new file mode 100644 index 00000000..f98ae6c2 --- /dev/null +++ b/pyconbalkan/speaker/api_urls.py @@ -0,0 +1,6 @@ +from rest_framework import routers + +from pyconbalkan.speaker.views import SpeakerViewSet + +router = routers.DefaultRouter() +router.register(r'speaker', SpeakerViewSet) \ No newline at end of file diff --git a/pyconbalkan/speaker/apps.py b/pyconbalkan/speaker/apps.py new file mode 100644 index 00000000..4e6e611a --- /dev/null +++ b/pyconbalkan/speaker/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class SpeakerConfig(AppConfig): + name = 'speaker' diff --git a/pyconbalkan/speaker/migrations/0001_initial.py b/pyconbalkan/speaker/migrations/0001_initial.py new file mode 100644 index 00000000..1b49b6a1 --- /dev/null +++ b/pyconbalkan/speaker/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.11 on 2018-04-26 21:50 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Speaker', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=False)), + ('name', models.CharField(max_length=50)), + ('job', models.CharField(max_length=100)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='SpeakerPhoto', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('profile_picture', models.ImageField(upload_to='static/img')), + ('speaker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='speaker.Speaker')), + ], + ), + ] diff --git a/pyconbalkan/speaker/migrations/__init__.py b/pyconbalkan/speaker/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/speaker/models.py b/pyconbalkan/speaker/models.py new file mode 100644 index 00000000..2dd71bc5 --- /dev/null +++ b/pyconbalkan/speaker/models.py @@ -0,0 +1,16 @@ +from django.db import models + +from pyconbalkan.core.models import SingleActiveModel + + +class Speaker(SingleActiveModel): + name = models.CharField(max_length=50) + job = models.CharField(max_length=100) + + def __str__(self): + return self.name + + +class SpeakerPhoto(models.Model): + speaker = models.ForeignKey(Speaker, related_name='images') + profile_picture = models.ImageField(upload_to="static/img") diff --git a/pyconbalkan/speaker/serializers.py b/pyconbalkan/speaker/serializers.py new file mode 100644 index 00000000..933baea3 --- /dev/null +++ b/pyconbalkan/speaker/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from pyconbalkan.speaker.models import Speaker + + +class SpeakerSerializer(serializers.ModelSerializer): + class Meta: + model = Speaker + fields = '__all__' diff --git a/pyconbalkan/speaker/tests.py b/pyconbalkan/speaker/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/pyconbalkan/speaker/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pyconbalkan/speaker/views.py b/pyconbalkan/speaker/views.py new file mode 100644 index 00000000..be56084e --- /dev/null +++ b/pyconbalkan/speaker/views.py @@ -0,0 +1,9 @@ +from rest_framework import viewsets + +from pyconbalkan.speaker.models import Speaker +from pyconbalkan.speaker.serializers import SpeakerSerializer + + +class SpeakerViewSet(viewsets.ModelViewSet): + queryset = Speaker.objects.all() + serializer_class = SpeakerSerializer diff --git a/pyconbalkan/urls.py b/pyconbalkan/urls.py index bc7936af..afd152d4 100644 --- a/pyconbalkan/urls.py +++ b/pyconbalkan/urls.py @@ -1,29 +1,20 @@ -"""pyconbalkan URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/1.11/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.conf.urls import url, include - 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) -""" -import os - -from django.conf.urls import url +from django.conf.urls import url, include from django.contrib import admin from django.views.static import serve -from pyconbalkan.core import views +from pyconbalkan.core import views, routers from pyconbalkan.settings import PDF_ROOT +from pyconbalkan.conference.api_urls import router as conference +from pyconbalkan.speaker.api_urls import router as speaker + + +router = routers.DefaultRouter() +router.extend(conference) +router.extend(speaker) urlpatterns = [ url(r'^$', views.home, name='index'), url(r'^coc$', serve, {'path': 'coc_pyconbalkan.pdf', 'document_root': PDF_ROOT}), url(r'^admin/', admin.site.urls), + url(r'^api/', include(router.urls)), # API ] diff --git a/requirements.txt b/requirements.txt index 15d934ec..a1c76a15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,13 @@ dj-database-url==0.5.0 dj-static==0.0.6 Django==1.11.11 +django-countries==5.3 +django-filter==1.1.0 +djangorestframework==3.8.2 gunicorn==19.7.1 -psycopg2==2.7.4 +Markdown==2.6.11 +Pillow==5.1.0 +psycopg2-binary==2.7.4 python-decouple==3.1 pytz==2018.3 static3==0.7.0