Add Job-ads DB object and serializers
This commit is contained in:
+3
-2
@@ -1,7 +1,7 @@
|
||||
"""File containing webapp app admin registers."""
|
||||
|
||||
from django.contrib import admin
|
||||
from webapp.models import Official, Role, Committee, Occupation
|
||||
from webapp.models import JobAd, Official, Role, Committee, Occupation
|
||||
from webapp.models import Feed, Tag, Event, Signup, SignupForm, TemplateQuestion
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from django.contrib.auth.models import Permission
|
||||
@@ -19,4 +19,5 @@ admin.site.register(TemplateQuestion, TranslationAdmin)
|
||||
admin.site.register(Committee, TranslationAdmin)
|
||||
admin.site.register(Official)
|
||||
admin.site.register(Occupation)
|
||||
admin.site.register(Role)
|
||||
admin.site.register(Role, TranslationAdmin)
|
||||
admin.site.register(JobAd, TranslationAdmin)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Generated by Django 2.1.5 on 2020-11-03 15:38
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
import webapp.utils
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('webapp', '0071_auto_20201006_1749'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='JobAd',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('title_fi', models.CharField(max_length=255, null=True)),
|
||||
('title_en', models.CharField(max_length=255, null=True)),
|
||||
('description', models.CharField(max_length=255)),
|
||||
('description_fi', models.CharField(max_length=255, null=True)),
|
||||
('description_en', models.CharField(max_length=255, null=True)),
|
||||
('content', models.TextField()),
|
||||
('content_fi', models.TextField(null=True)),
|
||||
('content_en', models.TextField(null=True)),
|
||||
('visible', models.BooleanField(default=True)),
|
||||
('created_at', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('autohide_at', models.DateTimeField(default=webapp.utils.month_from_now)),
|
||||
('autohide_enabled', models.BooleanField(default=False)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'JobAd',
|
||||
'verbose_name_plural': 'JobAds',
|
||||
},
|
||||
),
|
||||
]
|
||||
+54
-36
@@ -22,14 +22,14 @@ EMAIL_REGEX = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
|
||||
class Tag(models.Model):
|
||||
"""Model for tag."""
|
||||
|
||||
slug = models.SlugField(unique=True)
|
||||
name = models.CharField(max_length=127)
|
||||
icon = models.ImageField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Tag')
|
||||
verbose_name_plural = _('Tags')
|
||||
|
||||
slug = models.SlugField(unique=True)
|
||||
name = models.CharField(max_length=127)
|
||||
icon = models.ImageField()
|
||||
|
||||
def __str__(self):
|
||||
return _('Tag: {}').format(self.slug)
|
||||
|
||||
@@ -48,6 +48,10 @@ class BaseFeed(models.Model):
|
||||
class Feed(BaseFeed):
|
||||
"""Model representing feed."""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Feed')
|
||||
verbose_name_plural = _('Feeds')
|
||||
|
||||
publish_time = models.DateTimeField(default=timezone.now)
|
||||
autohide = models.DateTimeField(default=month_from_now)
|
||||
autohide_enabled = models.BooleanField(default=False)
|
||||
@@ -55,13 +59,13 @@ class Feed(BaseFeed):
|
||||
def __str__(self):
|
||||
return _('Feed: {}').format(self.title)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Feed')
|
||||
verbose_name_plural = _('Feeds')
|
||||
|
||||
|
||||
class Event(BaseFeed):
|
||||
"""Model for event."""
|
||||
"""Model for event in guild calendar"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Event')
|
||||
verbose_name_plural = _('Events')
|
||||
|
||||
start_time = models.DateTimeField(default=timezone.now)
|
||||
end_time = models.DateTimeField(default=timezone.now)
|
||||
@@ -72,26 +76,30 @@ class Event(BaseFeed):
|
||||
def __str__(self):
|
||||
return _('Event: {}').format(self.title)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Event')
|
||||
verbose_name_plural = _('Events')
|
||||
|
||||
|
||||
class TemplateQuestion(models.Model):
|
||||
"""Stores template questions for signup forms as JSONB"""
|
||||
"""
|
||||
NOT IMPLEMENTED!!!
|
||||
Stores template questions for signup forms as JSON format. Used in signup form creation
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Template question')
|
||||
verbose_name_plural = _('Template questions')
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
question = JSONField()
|
||||
|
||||
def __str__(self):
|
||||
return _('Template questions: {}').format(self.name)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Template question')
|
||||
verbose_name_plural = _('Template questions')
|
||||
|
||||
|
||||
class SignupForm(models.Model):
|
||||
"""Model for event signup form. Stores questions in JSONB."""
|
||||
"""Model for event signup form. Stores questions in JSON format."""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Signup form')
|
||||
verbose_name_plural = _('Signup forms')
|
||||
|
||||
title = models.CharField(max_length=255)
|
||||
start_time = models.DateTimeField(default=timezone.now)
|
||||
@@ -114,12 +122,15 @@ class SignupForm(models.Model):
|
||||
now = timezone.now()
|
||||
return self.start_time <= now and now < self.end_time
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Signup form')
|
||||
verbose_name_plural = _('Signup forms')
|
||||
|
||||
|
||||
class Signup(models.Model):
|
||||
"""
|
||||
In
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Sign-up')
|
||||
verbose_name_plural = _('Sign-ups')
|
||||
signupForm = models.ForeignKey('SignupForm', on_delete=models.CASCADE)
|
||||
time = models.DateTimeField(default=timezone.now)
|
||||
answer = JSONField()
|
||||
@@ -133,10 +144,6 @@ class Signup(models.Model):
|
||||
def __str__(self):
|
||||
return f"{self.signupForm}: {self.list_name} ({self.pk})"
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Sign-up')
|
||||
verbose_name_plural = _('Sign-ups')
|
||||
|
||||
|
||||
@receiver(post_save, sender=Signup)
|
||||
def email_on_signup(sender, instance, created, **kwargs):
|
||||
@@ -166,7 +173,6 @@ class BaseRole(models.Model):
|
||||
|
||||
class PresetRole(BaseRole):
|
||||
"""Model representing a preset occupation in the guild."""
|
||||
|
||||
description = models.TextField(_('Description'))
|
||||
|
||||
|
||||
@@ -177,8 +183,6 @@ class Committee(models.Model):
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""Meta class for Committee class."""
|
||||
|
||||
verbose_name = _('Committee')
|
||||
verbose_name_plural = _('Committees')
|
||||
|
||||
@@ -194,15 +198,11 @@ class Committee(models.Model):
|
||||
|
||||
class Role(PresetRole):
|
||||
"""
|
||||
Model for Role.
|
||||
|
||||
Model representing an active or historical occupation
|
||||
in the guild.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""Meta class for Role model."""
|
||||
|
||||
verbose_name = _('Role')
|
||||
verbose_name_plural = _('Roles')
|
||||
|
||||
@@ -241,8 +241,6 @@ class Official(models.Model):
|
||||
"""Model representing a guild official."""
|
||||
|
||||
class Meta:
|
||||
"""Meta class for Official class."""
|
||||
|
||||
verbose_name = _('Official')
|
||||
verbose_name_plural = _('Officials')
|
||||
|
||||
@@ -272,10 +270,30 @@ def save_user_official(sender, instance, **kwargs):
|
||||
instance.user.save()
|
||||
|
||||
|
||||
class JobAd(models.Model):
|
||||
"""Job advertisements shown on Corporate relations page"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('JobAd')
|
||||
verbose_name_plural = _('JobAds')
|
||||
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.CharField(max_length=255)
|
||||
content = models.TextField()
|
||||
visible = models.BooleanField(default=True)
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
autohide_at = models.DateTimeField(default=month_from_now)
|
||||
autohide_enabled = models.BooleanField(default=False)
|
||||
|
||||
|
||||
auditlog.register(Tag)
|
||||
auditlog.register(Feed)
|
||||
auditlog.register(Event)
|
||||
auditlog.register(SignupForm)
|
||||
auditlog.register(Signup)
|
||||
auditlog.register(PresetRole)
|
||||
auditlog.register(Role)
|
||||
auditlog.register(Committee)
|
||||
auditlog.register(Occupation)
|
||||
auditlog.register(Official)
|
||||
auditlog.register(JobAd)
|
||||
|
||||
@@ -169,3 +169,9 @@ class OccupationSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Occupation
|
||||
fields = ('role', 'start_date', 'end_date', 'officials')
|
||||
|
||||
|
||||
class JobAdSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = JobAd
|
||||
fields = ('title_fi', 'title_en', 'description_fi', 'description_en', 'content_fi', 'content_en', 'visible', 'autohide_at', 'autohide_enabled')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase, APIRequestFactory
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from webapp.models import Feed
|
||||
from webapp.serializers import FeedSerializer
|
||||
@@ -27,11 +27,7 @@ class FeedTestCase(APITestCase):
|
||||
self.assertTrue(status.is_success(response.status_code))
|
||||
|
||||
feeds = Feed.objects.all()
|
||||
serializer = FeedSerializer(
|
||||
feeds, many=True,
|
||||
context={
|
||||
"request": APIRequestFactory().get(r"http://testserver/api/events/")
|
||||
})
|
||||
serializer = FeedSerializer(feeds, many=True)
|
||||
self.assertEqual(response.data["results"], serializer.data)
|
||||
|
||||
def test_post_feed(self):
|
||||
@@ -50,13 +46,13 @@ class FeedTestCase(APITestCase):
|
||||
}
|
||||
# Try post without authentication
|
||||
response = self.client.post("/api/feed/", data, format="json")
|
||||
self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
self.assertEqual(Feed.objects.count(), 1)
|
||||
# Authenticate
|
||||
self.client.force_authenticate(user=self.authClient)
|
||||
response = self.client.post("/api/feed/", data, format="json")
|
||||
# Return success and check object was created
|
||||
self.assertTrue(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(Feed.objects.count(), 2)
|
||||
|
||||
created = Feed.objects.get(title_fi="testtitle")
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase, APIRequestFactory
|
||||
|
||||
from webapp.models import JobAd
|
||||
from webapp.serializers import JobAdSerializer
|
||||
|
||||
API = "/api/jobads/"
|
||||
|
||||
|
||||
class JobAdTestCase(APITestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.prefilled_jobad = JobAd.objects.create(
|
||||
title_fi="ABB Test",
|
||||
title_en="ABB Test",
|
||||
visible=True,
|
||||
description_fi="desc",
|
||||
description_en="desc",
|
||||
content_fi="lorem",
|
||||
content_en="lorem"
|
||||
)
|
||||
|
||||
username, password = "test_admin", "password123"
|
||||
self.authClient = User.objects.create_superuser(username, "myemail@test.com", password)
|
||||
|
||||
def test_get_jobads(self):
|
||||
response = self.client.get(API, format="json")
|
||||
expected = JobAdSerializer(self.prefilled_jobad).data
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["results"][0], expected)
|
||||
|
||||
def test_post_jobad(self):
|
||||
data = {
|
||||
"title_fi": "testtitle",
|
||||
"title_en": "testtitle",
|
||||
"visible": "True",
|
||||
"description_fi": "liirumlaarum",
|
||||
"description_en": "liirumlaarum",
|
||||
"content_fi": "lorem ipsum",
|
||||
"content_en": "lorem ipsum",
|
||||
"autohide_enabled": "True"
|
||||
}
|
||||
|
||||
# Try post without authentication
|
||||
response = self.client.post(API, data, format="json")
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
self.assertEqual(JobAd.objects.count(), 1)
|
||||
# Authenticate
|
||||
self.client.force_authenticate(user=self.authClient)
|
||||
response = self.client.post(API, data, format="json")
|
||||
# Return success and check object was created
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(JobAd.objects.count(), 2)
|
||||
+10
-20
@@ -6,69 +6,59 @@ from webapp.models import *
|
||||
|
||||
@register(BaseFeed)
|
||||
class BaseFeedTranslationOptions(TranslationOptions):
|
||||
"""Class for base feed translation options."""
|
||||
|
||||
fields = ('title', 'description', 'content')
|
||||
|
||||
|
||||
@register(Feed)
|
||||
class FeedTranslationOptions(TranslationOptions):
|
||||
"""Class for feed translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(Tag)
|
||||
class TagTranslationOptions(TranslationOptions):
|
||||
"""Class for tag translation options."""
|
||||
|
||||
fields = ('name',)
|
||||
|
||||
|
||||
@register(Event)
|
||||
class EventTranslationOptions(TranslationOptions):
|
||||
"""Class for event translation options."""
|
||||
|
||||
fields = ('location',)
|
||||
|
||||
|
||||
@register(Signup)
|
||||
class SignupTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(SignupForm)
|
||||
class SignupFormTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ('title',)
|
||||
|
||||
|
||||
@register(TemplateQuestion)
|
||||
class TemplateQuestionTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(BaseRole)
|
||||
class BaseRoleTranslationOptions(TranslationOptions):
|
||||
"""Class for base role translation options"""
|
||||
|
||||
fields = ('name',)
|
||||
|
||||
|
||||
@register(PresetRole)
|
||||
class PresetRoleTranslationOptions(TranslationOptions):
|
||||
"""Class for PresetRole translation options."""
|
||||
|
||||
fields = ('description',)
|
||||
|
||||
|
||||
@register(Role)
|
||||
class RoleTranslationOptions(TranslationOptions):
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(Committee)
|
||||
class CommitteeTranslationOptions(TranslationOptions):
|
||||
"""Class for PresetRole translation options."""
|
||||
|
||||
fields = ('name',)
|
||||
|
||||
|
||||
@register(JobAd)
|
||||
class JobAdTranslationOptions(TranslationOptions):
|
||||
fields = ('title', 'description', 'content',)
|
||||
|
||||
@@ -22,6 +22,7 @@ router.register(r'contacts', ContactsViewSet)
|
||||
router.register(r'committees', CommitteeViewSet)
|
||||
router.register(r'questions', SavedQuestionsViewSet)
|
||||
router.register(r'tags', TagsViewSet)
|
||||
router.register(r'jobads', JobAdViewSet)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^api/', include(router.urls)),
|
||||
|
||||
+8
-4
@@ -19,10 +19,8 @@ from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission
|
||||
from jsonschema import validate
|
||||
from jsonschema.exceptions import ValidationError
|
||||
|
||||
from webapp.models import Event, SignupForm, Signup, TemplateQuestion, Feed, Committee, Occupation, Tag
|
||||
from webapp.serializers import (EventSerializer, SignupFormSerializer, SignupSerializer,
|
||||
SavedQuestionsSerializer, FeedSerializer, CommitteeSerializer,
|
||||
OccupationSerializer, TagSerializer)
|
||||
from webapp.models import *
|
||||
from webapp.serializers import *
|
||||
from webapp.utils import decode_base64_file
|
||||
|
||||
|
||||
@@ -215,6 +213,12 @@ class TagsViewSet(ReadOnlyModelViewSet):
|
||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||
|
||||
|
||||
class JobAdViewSet(ModelViewSet):
|
||||
queryset = JobAd.objects.all()
|
||||
serializer_class = JobAdSerializer
|
||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
def about_view(request, *args, **kwargs):
|
||||
"""Render about page."""
|
||||
|
||||
Reference in New Issue
Block a user