From 312ed577143c454a7c85a49198c62a2f9c6e3a0d Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Wed, 22 Mar 2017 19:09:58 +0200 Subject: [PATCH 1/6] Move changes from feature-member --- members/models.py | 122 ++++++++++++---------------------------------- members/views.py | 1 - 2 files changed, 31 insertions(+), 92 deletions(-) diff --git a/members/models.py b/members/models.py index aa52019..7fefdd0 100644 --- a/members/models.py +++ b/members/models.py @@ -4,115 +4,55 @@ from datetime import datetime from io import StringIO import csv - -class Member(models.Model): +class BaseMember(models.Model): ''' - Member model represets one member on the registry + Base model for member. ''' - first_name = models.CharField(max_length=127) last_name = models.CharField(max_length=127) email = models.EmailField() POR = models.CharField(max_length=255) # place of residence AYY = models.BooleanField(default=False) jas = models.BooleanField(default=False) - created = models.DateTimeField(default=timezone.now) - paid = models.DateTimeField(default=datetime.fromtimestamp(0)) - - def get_dict(self): - return { - 'id': self.id, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'email': self.email, - 'POR': self.POR, - 'AYY': self.AYY, - 'jas': self.jas, - 'created': date2str(self.created), - 'paid': date2str(self.paid), - } - @classmethod - def create_from_dict(cls, d): - mbr = cls() - mbr.update_from_dict(d) - return mbr - - def update_from_dict(self, d): - dmap = { - 'first_name': reverse_map('first_name'), - 'last_name': reverse_map('last_name'), - 'email': reverse_map('email'), - 'POR': reverse_map('POR'), - 'AYY': reverse_map('AYY'), - 'jas': reverse_map('jas'), - 'paid': reverse_map('paid', str2date), - } - for k, v in d.items(): - try: - self.__setattr__(dmap[k].key, dmap[k].parser(v)) - except KeyError: - pass - self.save() - - @classmethod - def import_csv(cls, csv_string): - reader = csv.reader(StringIO(csv_string.strip())) - response = {"status": "success", "errors": []} - try: - data = list(reader) - except ValueError: - return {"status": "failure", "errors": ["could not parse csv file"]} - - affirmative_answers = ['yes', 'y', '1', 'true', "kyllä", "khyl"] - for row in data: - - try: - obj = cls.objects.create( - first_name=row[0], - last_name=row[1], - email=row[2], - POR=row[3], - AYY=row[4].lower() in affirmative_answers, - jas=row[5].lower() in affirmative_answers, - paid=timezone.now() - ) - print("added obj {}".format(obj)) - - except: - response["status"] = "failure" - response["errors"].append("failure adding item {}".format(", ".join(row))) - - return response - - def __str__(self): - return "{} {}".format(self.first_name, self.last_name) + class Meta: + abstract = True -class MemberRequest(models.Model): - member = models.ForeignKey(Member) +class MemberRequest(BaseMember): + ''' + Member request model represents one member request. + ''' + submitted = models.DateTimeField(default=timezone.now) + + +class Payment(models.Model): + ''' + Payment model representing one payment event + ''' + date = models.DateTimeField(default=datetime.fromtimestamp(0)) + source = models.CharField(max_length=255) + first_name = models.CharField(max_length=255) + last_name = models.CharField(max_length=255) + email = models.EmailField(max_length=255) + member = models.ForeignKey('Member', on_delete=models.SET_NULL, blank=True, null=True) def get_dict(self): return { 'id': self.id, - 'member': self.member.get_dict(), + 'date': date2str(self.date), + 'source': self.source, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'email': self.email, + 'member': self.member.get_dict() if self.member else {} } -def date2str(date): +class Member(BaseMember): ''' - Convert date to a standard date string + Member model represets one member on the registry. ''' - if date is None: - return None - return date.strftime("%Y-%m-%d %H:%M:%S") + created = models.DateTimeField(default=timezone.now) + paid = models.DateTimeField(default=timezone.now) #this needs to be assigned as Payment.date - -def str2date(s): - return datetime.strptime(s,"%Y-%m-%d %H:%M:%S") - - -class reverse_map: - def __init__(self, key, parser=lambda x: x): - self.key = key - self.parser = parser diff --git a/members/views.py b/members/views.py index f710860..c4a5920 100644 --- a/members/views.py +++ b/members/views.py @@ -32,7 +32,6 @@ class MembersList(generics.ListCreateAPIView): permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) - class MemberDetails(generics.RetrieveUpdateDestroyAPIView): queryset = Member.objects.all() serializer_class = MemberSerializer From bede518a5da14c0480f7dd74b54d7412c51e3b05 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Wed, 22 Mar 2017 19:55:04 +0200 Subject: [PATCH 2/6] Remove members_index.html --- members/templates/members_index.html | 31 ---------------------------- 1 file changed, 31 deletions(-) delete mode 100644 members/templates/members_index.html diff --git a/members/templates/members_index.html b/members/templates/members_index.html deleted file mode 100644 index 6cac673..0000000 --- a/members/templates/members_index.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "members_base.html" %} - -{% block content %} -
- - - - - - -
- -
-
-{% endblock content %} From dd01b44445f6e552bbbf09f1039cfce4c7bf10fa Mon Sep 17 00:00:00 2001 From: henu Date: Wed, 29 Mar 2017 06:47:02 +0300 Subject: [PATCH 3/6] Add submitted to request serializer --- members/serializers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/members/serializers.py b/members/serializers.py index de62040..d4602e4 100644 --- a/members/serializers.py +++ b/members/serializers.py @@ -40,6 +40,7 @@ class MemberSerializer(serializers.Serializer): class MemberRequestSerializer(serializers.ModelSerializer): id = serializers.IntegerField(read_only=True) + submitted = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") member = MemberSerializer() class Meta: From ea36d4b193efc84a1a3f257bfe20b488ec6c2164 Mon Sep 17 00:00:00 2001 From: henu Date: Wed, 29 Mar 2017 19:12:46 +0300 Subject: [PATCH 4/6] Fix member serializers, add own requirements to gitignore --- .gitignore | 2 ++ members/serializers.py | 29 +++++++++++++++++++++++++---- misc/create_dummydata.py | 25 ++++++++++++++++++++----- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index aebd4f5..47003c7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ logs/ /media/ node_modules/ /.coverage +db.sqlite3 +requirements_henu.txt diff --git a/members/serializers.py b/members/serializers.py index d4602e4..abcd13f 100644 --- a/members/serializers.py +++ b/members/serializers.py @@ -41,8 +41,29 @@ class MemberSerializer(serializers.Serializer): class MemberRequestSerializer(serializers.ModelSerializer): id = serializers.IntegerField(read_only=True) submitted = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") - member = MemberSerializer() + first_name = serializers.CharField(required=True, max_length=127) + last_name = serializers.CharField(required=True, max_length=127) + email = serializers.EmailField(min_length=None, max_length=None, required=True) + POR = serializers.CharField(max_length=255) + AYY = serializers.BooleanField(default=False) + jas = serializers.BooleanField(default=False) - class Meta: - model = MemberRequest - fields = ('id', 'member') + def created(self, validated_data): + ''' + Create and return a new MemberRequest instance, given the validated data. + ''' + return MemberRequest.objects.create(**validated_data) + + def update(self, instance, validated_data): + ''' + Update and return an existing Member request instance given the validated data. + ''' + instance.submitted = validated_data.get('submitted', instance.submitted) + instance.first_name = validated_data.get('first_name', instance.first_name) + instance.last_name = validated_data.get('last_name', instance.last_name) + instance.email = validated_data.get('email', instance.email) + instance.POR = validated_data.get('POR', instance.POR) + instance.AYY = validated_data.get('AYY', instance.AYY) + instance.jas = validated_data.get('jas', instance.jas) + instance.save() + return instance diff --git a/misc/create_dummydata.py b/misc/create_dummydata.py index f4aa513..2012ffa 100644 --- a/misc/create_dummydata.py +++ b/misc/create_dummydata.py @@ -1,4 +1,4 @@ -import sys +import sys import os import time import random @@ -14,8 +14,8 @@ from misc.namegenerator import generate_names MEMBERAMOUNT = 30 MEMBERREQUESTAMOUNT = 3 -print ("""THIS SCRIPT WILL GENERATE DUMMY VALUES TO DATABASE -AND SHOULD __NEVER__ BE RUN ON PRODUCTION. +print ("""THIS SCRIPT WILL GENERATE DUMMY VALUES TO DATABASE +AND SHOULD __NEVER__ BE RUN ON PRODUCTION. IF YOU ARE ON PRODUCTION ABORT (ctrl-c) IMMEDIATELY!!!! CONTINUING IN 10 SECONDS""") time.sleep(10) @@ -37,5 +37,20 @@ for i in range(MEMBERAMOUNT): jas=jas) -for m in list(Member.objects.all())[:5]: - MemberRequest.objects.create(member=m) +# for m in list(Member.objects.all())[:5]: +# MemberRequest.objects.create(member=m) +names = generate_names(MEMBERREQUESTAMOUNT) +maildomains = ["example.coms",'ggmail.om',"notmail.dom"] #intentionally wrong +places = ["Helsinki", "Espoo", "Korso","Kerava", "Kouvostoliitto"] +for i in range(MEMBERREQUESTAMOUNT): + f,l = names[i] + mail = "{}.{}@{}".format(f.lower(),l.lower(),random.choice(maildomains)) + por = random.choice(places) + ayy = random.randint(0,1) + jas = random.randint(0,1) + Member.objects.create(first_name=f, + last_name=l, + email=mail, + POR=por, + AYY=ayy, + jas=jas) From a947f21652bf44ca0b8af68a6d5166b1c2db4593 Mon Sep 17 00:00:00 2001 From: henu Date: Wed, 29 Mar 2017 19:37:56 +0300 Subject: [PATCH 5/6] Change memberRequest model to Request model --- members/admin.py | 4 +- members/migrations/0003_auto_20170329_1928.py | 67 +++++++++++++++++++ members/models.py | 5 +- members/serializers.py | 4 +- members/views.py | 6 +- 5 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 members/migrations/0003_auto_20170329_1928.py diff --git a/members/admin.py b/members/admin.py index bacee5d..7550b85 100644 --- a/members/admin.py +++ b/members/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from members.models import Member, MemberRequest +from members.models import Member, Request # Register your models here. admin.site.register(Member) -admin.site.register(MemberRequest) +admin.site.register(Request) diff --git a/members/migrations/0003_auto_20170329_1928.py b/members/migrations/0003_auto_20170329_1928.py new file mode 100644 index 0000000..ddffdda --- /dev/null +++ b/members/migrations/0003_auto_20170329_1928.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-03-29 16:28 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0002_auto_20170329_1857'), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(default=datetime.datetime(1970, 1, 1, 2, 0))), + ('source', models.CharField(max_length=255)), + ('first_name', models.CharField(max_length=255)), + ('last_name', models.CharField(max_length=255)), + ('email', models.EmailField(max_length=255)), + ], + ), + migrations.CreateModel( + name='Request', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=127)), + ('last_name', models.CharField(max_length=127)), + ('email', models.EmailField(max_length=254)), + ('POR', models.CharField(default='ei_tiedossa', max_length=255)), + ('AYY', models.BooleanField(default=False)), + ('jas', models.BooleanField(default=False)), + ('submitted', models.DateTimeField(default=django.utils.timezone.now)), + ], + options={ + 'abstract': False, + }, + ), + migrations.RemoveField( + model_name='memberrequest', + name='member', + ), + migrations.AlterField( + model_name='member', + name='POR', + field=models.CharField(default='ei_tiedossa', max_length=255), + ), + migrations.AlterField( + model_name='member', + name='paid', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.DeleteModel( + name='MemberRequest', + ), + migrations.AddField( + model_name='payment', + name='member', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='members.Member'), + ), + ] diff --git a/members/models.py b/members/models.py index 7fefdd0..744bf94 100644 --- a/members/models.py +++ b/members/models.py @@ -11,7 +11,7 @@ class BaseMember(models.Model): first_name = models.CharField(max_length=127) last_name = models.CharField(max_length=127) email = models.EmailField() - POR = models.CharField(max_length=255) # place of residence + POR = models.CharField(default="ei_tiedossa", max_length=255) # place of residence AYY = models.BooleanField(default=False) jas = models.BooleanField(default=False) @@ -19,7 +19,7 @@ class BaseMember(models.Model): abstract = True -class MemberRequest(BaseMember): +class Request(BaseMember): ''' Member request model represents one member request. ''' @@ -55,4 +55,3 @@ class Member(BaseMember): ''' created = models.DateTimeField(default=timezone.now) paid = models.DateTimeField(default=timezone.now) #this needs to be assigned as Payment.date - diff --git a/members/serializers.py b/members/serializers.py index 097d6c1..c473ff5 100644 --- a/members/serializers.py +++ b/members/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from django.utils import timezone from datetime import datetime -from members.models import Member, MemberRequest +from members.models import Member, Request from django.conf import settings @@ -37,7 +37,7 @@ class MemberSerializer(serializers.Serializer): instance.save() return instance -class MemberRequestSerializer(serializers.ModelSerializer): +class MemberRequestSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) submitted = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") first_name = serializers.CharField(required=True, max_length=127) diff --git a/members/views.py b/members/views.py index f3e6316..8570dba 100644 --- a/members/views.py +++ b/members/views.py @@ -4,7 +4,7 @@ from django.views.decorators.http import require_http_methods from django.views.decorators.csrf import ensure_csrf_cookie from django.http import HttpResponse, HttpResponseBadRequest from django.core.exceptions import ValidationError -from members.models import Member, MemberRequest +from members.models import Member, Request import json from django.core.mail import send_mail import requests @@ -39,13 +39,13 @@ class MemberDetails(generics.RetrieveUpdateDestroyAPIView): throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) class MemberRequestList(generics.ListCreateAPIView): - queryset = MemberRequest.objects.all() + queryset = Request.objects.all() serializer_class = MemberRequestSerializer permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) class MemberRequestDetail(generics.RetrieveUpdateDestroyAPIView): - queryset = MemberRequest.objects.all() + queryset = Request.objects.all() serializer_class = MemberRequestSerializer permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) From d093a9167c7ed4c245d4bb884b0ba42cf74fd1e0 Mon Sep 17 00:00:00 2001 From: henu Date: Wed, 29 Mar 2017 19:38:33 +0300 Subject: [PATCH 6/6] Fix create_dummydata script models --- misc/create_dummydata.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/create_dummydata.py b/misc/create_dummydata.py index 2012ffa..693582c 100644 --- a/misc/create_dummydata.py +++ b/misc/create_dummydata.py @@ -9,7 +9,7 @@ from django.conf import settings django.setup() #django related stuff should be imported below this -from members.models import Member, MemberRequest +from members.models import Member, Request from misc.namegenerator import generate_names MEMBERAMOUNT = 30 MEMBERREQUESTAMOUNT = 3 @@ -48,7 +48,7 @@ for i in range(MEMBERREQUESTAMOUNT): por = random.choice(places) ayy = random.randint(0,1) jas = random.randint(0,1) - Member.objects.create(first_name=f, + Request.objects.create(first_name=f, last_name=l, email=mail, POR=por,