From e2a449633ae6a06311457bcf2f29b6f60a8cb576 Mon Sep 17 00:00:00 2001 From: ArturBaybulatov Date: Tue, 17 May 2016 16:30:18 +0300 Subject: [PATCH] Setup DRF --- .gitignore | 4 +- api/filters.py | 130 ------------------ api/serializers.py | 51 ------- api/urls.py | 6 +- api/views.py | 27 +++- archilance/management/__init__.py | 0 archilance/management/commands/__init__.py | 0 archilance/management/commands/seed_data.py | 78 +++++++++++ archilance/settings/base.py | 18 +-- archilance/urls.py | 6 +- assets/index.js | 35 +++++ projects/filters.py | 12 ++ projects/migrations/0001_initial.py | 6 +- ...516_1439.py => 0002_auto_20160517_0903.py} | 4 +- projects/models.py | 8 +- projects/serializers.py | 24 ++++ projects/views.py | 2 +- specializations/filters.py | 16 +++ specializations/migrations/0001_initial.py | 2 +- specializations/models.py | 10 +- specializations/serializers.py | 20 +++ templates/_layout.html | 25 ++++ templates/test.html | 11 ++ users/admin.py | 4 +- users/filters.py | 14 ++ users/migrations/0001_initial.py | 8 +- users/models.py | 16 +-- users/serializers.py | 41 ++++++ users/views.py | 12 +- 29 files changed, 350 insertions(+), 240 deletions(-) delete mode 100755 api/filters.py delete mode 100755 api/serializers.py create mode 100644 archilance/management/__init__.py create mode 100644 archilance/management/commands/__init__.py create mode 100644 archilance/management/commands/seed_data.py create mode 100644 assets/index.js create mode 100755 projects/filters.py rename projects/migrations/{0002_auto_20160516_1439.py => 0002_auto_20160517_0903.py} (89%) create mode 100755 projects/serializers.py create mode 100755 specializations/filters.py create mode 100755 specializations/serializers.py create mode 100644 templates/_layout.html create mode 100644 templates/test.html create mode 100755 users/filters.py create mode 100755 users/serializers.py diff --git a/.gitignore b/.gitignore index 3179668..5c00400 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.pyc -.idea/ \ No newline at end of file +.idea/ +env/ + diff --git a/api/filters.py b/api/filters.py deleted file mode 100755 index f726c70..0000000 --- a/api/filters.py +++ /dev/null @@ -1,130 +0,0 @@ -# import rest_framework_filters as filters -# -# from common import models -# -# -# class Category(filters.FilterSet): -# class Meta: -# model = models.Category -# -# # icon = ... -# adverts = filters.RelatedFilter('api.filters.Advert') -# children = filters.RelatedFilter('api.filters.Category') -# hidden = filters.AllLookupsFilter() -# level = filters.AllLookupsFilter() -# lft = filters.AllLookupsFilter() -# name = filters.AllLookupsFilter() -# parent = filters.RelatedFilter('api.filters.Category') -# rght = filters.AllLookupsFilter() -# slug = filters.AllLookupsFilter() -# tree_id = filters.AllLookupsFilter() -# -# -# class Advert(filters.FilterSet): -# class Meta: -# model = models.Advert -# -# body = filters.AllLookupsFilter() -# category = filters.RelatedFilter('api.filters.Category') -# colors = filters.RelatedFilter('api.filters.Color') -# contact_name = filters.AllLookupsFilter() -# contact_phone = filters.RelatedFilter('api.filters.ContactPhone') -# created_at = filters.AllLookupsFilter() -# expires_at = filters.AllLookupsFilter() -# gender = filters.AllLookupsFilter() -# id = filters.AllLookupsFilter() -# initial_price = filters.AllLookupsFilter() -# location = filters.RelatedFilter('api.filters.Location') -# pictures = filters.RelatedFilter('api.filters.AdvertPicture') -# price = filters.AllLookupsFilter() -# promos = filters.RelatedFilter('api.filters.Promo') -# receive_email_notifications = filters.AllLookupsFilter() -# reservation = filters.RelatedFilter('api.filters.Reservation') -# saved_by = filters.RelatedFilter('api.filters.User') -# state = filters.AllLookupsFilter() -# title = filters.AllLookupsFilter() -# updated_at = filters.AllLookupsFilter() -# user = filters.RelatedFilter('api.filters.User') -# -# -# class AdvertPicture(filters.FilterSet): -# class Meta: -# model = models.AdvertPicture -# -# # file = ... -# active = filters.AllLookupsFilter() -# advert = filters.RelatedFilter('api.filters.Advert') -# id = filters.AllLookupsFilter() -# main = filters.AllLookupsFilter() -# uploaded_at = filters.AllLookupsFilter() -# user = filters.RelatedFilter('api.filters.User') -# -# -# class Color(filters.FilterSet): -# class Meta: -# model = models.Color -# -# id = filters.AllLookupsFilter() -# name = filters.AllLookupsFilter() -# value = filters.AllLookupsFilter() -# -# -# class Location(filters.FilterSet): -# class Meta: -# model = models.Location -# -# adverts = filters.RelatedFilter('api.filters.Advert') -# # children = filters.RelatedFilter('api.filters.Location') -# id = filters.AllLookupsFilter() -# level = filters.AllLookupsFilter() -# lft = filters.AllLookupsFilter() -# name = filters.AllLookupsFilter() -# parent = filters.RelatedFilter('api.filters.Location') -# rght = filters.AllLookupsFilter() -# subway_line_color = filters.AllLookupsFilter() -# tree_id = filters.AllLookupsFilter() -# type = filters.AllLookupsFilter() -# users = filters.RelatedFilter('api.filters.User') -# -# -# class User(filters.FilterSet): -# class Meta: -# model = models.User -# -# adverts = filters.RelatedFilter('api.filters.Advert') -# contact_phones = filters.RelatedFilter('api.filters.ContactPhone') -# date_joined = filters.AllLookupsFilter() -# email = filters.AllLookupsFilter() -# first_name = filters.AllLookupsFilter() -# id = filters.AllLookupsFilter() -# is_active = filters.AllLookupsFilter() -# is_staff = filters.AllLookupsFilter() -# is_superuser = filters.AllLookupsFilter() -# last_login = filters.AllLookupsFilter() -# location = filters.RelatedFilter('api.filters.Location') -# password = filters.AllLookupsFilter() -# promos = filters.RelatedFilter('api.filters.Promo') -# social_auth_id = filters.AllLookupsFilter() -# subscribed_to_newsletter = filters.AllLookupsFilter() -# type = filters.AllLookupsFilter() -# username = filters.AllLookupsFilter() -# -# -# class ContactPhone(filters.FilterSet): -# class Meta: -# model = models.ContactPhone -# -# -# class Reservation(filters.FilterSet): -# class Meta: -# model = models.Reservation -# -# -# class Promo(filters.FilterSet): -# class Meta: -# model = models.Promo -# -# -# class PromoType(filters.FilterSet): -# class Meta: -# model = models.PromoType diff --git a/api/serializers.py b/api/serializers.py deleted file mode 100755 index 61143eb..0000000 --- a/api/serializers.py +++ /dev/null @@ -1,51 +0,0 @@ -from rest_framework.serializers import ModelSerializer - -from projects.models import Project -from specializations.models import Specialization -from users.models import CustomUser - - -class CustomUserSerializer(ModelSerializer): - class Meta: - model = CustomUser - - fields = ( - 'id', - 'email', - 'firstname', - 'is_active', - 'is_admin', - 'lastname', - ) - - -class SpecializationSerializer(ModelSerializer): - class Meta: - model = Specialization - - fields = ( - 'id', - 'level', - 'lft', - 'name', - 'parent', - 'rght', - 'tree_id', - ) - - -class ProjectSerializer(ModelSerializer): - class Meta: - model = Project - - fields = ( - 'id', - 'name', - 'price', - 'specialization', - 'text', - 'user', - ) - - user = CustomUserSerializer() - specialization = SpecializationSerializer() diff --git a/api/urls.py b/api/urls.py index a88803c..cc5dd5a 100755 --- a/api/urls.py +++ b/api/urls.py @@ -1,8 +1,12 @@ from rest_framework import routers -from .views import ProjectViewSet +from .views import ProjectViewSet, SpecializationViewSet, UserViewSet router = routers.DefaultRouter() + router.register(r'projects', ProjectViewSet) +router.register(r'specializations', SpecializationViewSet) +router.register(r'users', UserViewSet) + urlpatterns = router.urls diff --git a/api/views.py b/api/views.py index 229b25d..965a621 100755 --- a/api/views.py +++ b/api/views.py @@ -1,10 +1,31 @@ from rest_framework.viewsets import ModelViewSet from projects.models import Project -from .serializers import ProjectSerializer -# from .filters import ProjectFilter +from projects.serializers import ProjectSerializer +from projects.filters import ProjectFilterSet + +from specializations.models import Specialization +from specializations.serializers import SpecializationSerializer +from specializations.filters import SpecializationFilterSet + +from users.models import User +from users.serializers import UserSerializer +from users.filters import UserFilterSet + class ProjectViewSet(ModelViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer - # filter_class = ProjectFilter + filter_class = ProjectFilterSet + + +class SpecializationViewSet(ModelViewSet): + queryset = Specialization.objects.all() + serializer_class = SpecializationSerializer + filter_class = SpecializationFilterSet + + +class UserViewSet(ModelViewSet): + queryset = User.objects.all() + serializer_class = UserSerializer + filter_class = UserFilterSet diff --git a/archilance/management/__init__.py b/archilance/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/archilance/management/commands/__init__.py b/archilance/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/archilance/management/commands/seed_data.py b/archilance/management/commands/seed_data.py new file mode 100644 index 0000000..036bc48 --- /dev/null +++ b/archilance/management/commands/seed_data.py @@ -0,0 +1,78 @@ +# from cms_pages.models import Menu, CmsPage +# from django.contrib import sites +# from django.core.files import File +from django.core.management import BaseCommand +# from django.db import connection +# from django.db.models import Q +from django.utils import timezone +# from pprint import pprint, pformat +# from wagtail.wagtailcore.models import Page +# import copy +# import eav.models +# import inspect +# import itertools +# import json +# import os +import pydash as _; _.map = _.map_; _.filter = _.filter_ +import random +# import requests +# import util + +from users.models import User + + +class Command(BaseCommand): + def handle(self, *args, **options): + print('---------------------------------------') + print('Generating data...') + print('---------------------------------------') + + + def take(coll, n): + chunk = coll[0:n] + del coll[0:n] + return chunk + + def take_random(coll, n): + if n == 0: + return [] + + chunk = _.sample(coll, n) + + for item in chunk: + coll.remove(item) + + return chunk + + def take_one_random(coll): + if len(coll) == 0: + return None + + return coll.pop(_.random(0, len(coll)-1)) + + def random_phone(): + return '+7' + str(_.sample((917, 964, 965, 987, 912, 935))) + str(_.random(1000000, 9999999)) + + def random_date(): + return timezone.datetime(_.random(2012, 2018), _.random(1, 12), _.random(1, 28)) + + def random_amount(): + return random.random() * random.choice((100, 1000, 10000)) + + + User.objects.create_superuser('admin@example.com', '123456') + + def create_user(i): + username = 'user-%s' % i + + return User.objects.create( + first_name='User-%s' % i, + email='%s@example.com' % username, + is_active=_.sample((True, False)), + ) + + users = _.times(create_user, 100) + + for user in users: + user.set_password('123') + user.save() diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 5909b29..38df455 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -1,15 +1,3 @@ -""" -Django settings for archilance project. - -Generated by 'django-admin startproject' using Django 1.9.6. - -For more information on this file, see -https://docs.djangoproject.com/en/1.9/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.9/ref/settings/ -""" - import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) @@ -40,6 +28,7 @@ DJANGO_APPS = [ ] THIRD_PARTY_APPS = [ + 'django_extensions', 'mptt', 'registration', 'rest_framework', @@ -47,6 +36,7 @@ THIRD_PARTY_APPS = [ LOCAL_APPS = [ 'api', + 'archilance', 'projects', 'specializations', 'users', @@ -160,7 +150,7 @@ STATICFILES_DIRS = ( os.path.join(ROOT_DIR, 'assets'), ) -AUTH_USER_MODEL = 'users.CustomUser' +AUTH_USER_MODEL = 'users.User' ACCOUNT_ACTIVATION_DAYS = 7 REGISTRATION_AUTO_LOGIN = True LOGIN_REDIRECT_URL = '/projects/' @@ -179,7 +169,7 @@ REST_FRAMEWORK = { 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', ], - 'PAGE_SIZE': 50, + 'PAGE_SIZE': 10, 'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters } diff --git a/archilance/urls.py b/archilance/urls.py index 37bd38f..addbc88 100644 --- a/archilance/urls.py +++ b/archilance/urls.py @@ -1,13 +1,15 @@ +from django.conf import settings from django.conf.urls import url, include -from django.contrib import admin from django.conf.urls.static import static -from django.conf import settings +from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns +from django.views.generic import TemplateView from .views import HomeTemplateView urlpatterns = [ url(r'^$', HomeTemplateView.as_view()), + url(r'^test/$', TemplateView.as_view(template_name='test.html'), name='test'), url(r'^projects/', include('projects.urls')), url(r'^specialization/', include('specializations.urls')), url(r'^users/', include('registration.backends.default.urls')), diff --git a/assets/index.js b/assets/index.js new file mode 100644 index 0000000..aa4f285 --- /dev/null +++ b/assets/index.js @@ -0,0 +1,35 @@ +window.g = window + +var app = angular.module('app', []) + + +app.config(['$interpolateProvider', '$httpProvider', + function($interpolateProvider, $httpProvider) { + $interpolateProvider.startSymbol('{(') + $interpolateProvider.endSymbol(')}') + + $httpProvider.defaults.xsrfCookieName = 'csrftoken' + $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken' + + $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest' + + //$routeProvider.when('/', {templateUrl: '.....'}) + }, +]) + + +app.run(['$rootScope', '$timeout', '$http', + function run($rootScope, $timeout, $http) { + g.$http = $http // Debug + g.$timeout = $timeout // Debug + }, +]) + + +app.controller('TestCtrl', ['$scope', '$http', function TestCtrl($scope, $http) { + var test = g.test = this + + $http.get('/api/users/?is_admin=False').then(function(res) { + test.users = res.data.results + }) +}]) diff --git a/projects/filters.py b/projects/filters.py new file mode 100755 index 0000000..bf586d7 --- /dev/null +++ b/projects/filters.py @@ -0,0 +1,12 @@ +from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter +from .models import Project + +class ProjectFilterSet(FilterSet): + name = AllLookupsFilter() + price = AllLookupsFilter() + text = AllLookupsFilter() + user = RelatedFilter('users.filters.UserFilterSet') + specialization = RelatedFilter('specializations.filters.SpecializationFilterSet') + + class Meta: + model = Project diff --git a/projects/migrations/0001_initial.py b/projects/migrations/0001_initial.py index 8ef4b6c..181f75a 100644 --- a/projects/migrations/0001_initial.py +++ b/projects/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.6 on 2016-05-16 14:39 +# Generated by Django 1.9.6 on 2016-05-17 09:03 from __future__ import unicode_literals from django.db import migrations, models @@ -37,11 +37,11 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=255)), ('price', models.DecimalField(decimal_places=2, max_digits=10)), ('text', models.TextField(blank=True)), - ('specialization', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='spec', to='specializations.Specialization')), + ('specialization', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='specializations.Specialization')), ], options={ - 'verbose_name': 'Проект', 'verbose_name_plural': 'Проекты', + 'verbose_name': 'Проект', }, ), ] diff --git a/projects/migrations/0002_auto_20160516_1439.py b/projects/migrations/0002_auto_20160517_0903.py similarity index 89% rename from projects/migrations/0002_auto_20160516_1439.py rename to projects/migrations/0002_auto_20160517_0903.py index b44991e..75cc8af 100644 --- a/projects/migrations/0002_auto_20160516_1439.py +++ b/projects/migrations/0002_auto_20160517_0903.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.6 on 2016-05-16 14:39 +# Generated by Django 1.9.6 on 2016-05-17 09:03 from __future__ import unicode_literals from django.conf import settings @@ -20,7 +20,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='project', name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='customers', to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='projects', to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='portfoliophoto', diff --git a/projects/models.py b/projects/models.py index 552687f..2407e15 100644 --- a/projects/models.py +++ b/projects/models.py @@ -1,6 +1,6 @@ from django.db import models -from users.models import CustomUser +from users.models import User from specializations.models import Specialization @@ -11,8 +11,8 @@ class Project(models.Model): # type_work = models.CharField() # budget = models.CharField() # cro = models.BooleanField(default=False) - user = models.ForeignKey(CustomUser, related_name='customers') - specialization = models.ForeignKey(Specialization, related_name='spec', null=True) + user = models.ForeignKey(User, related_name='projects') + specialization = models.ForeignKey(Specialization, related_name='projects', blank=True, null=True) # TODO: Make required def __str__(self): return self.name @@ -25,7 +25,7 @@ class Project(models.Model): class Portfolio(models.Model): name = models.CharField(max_length=255) description = models.TextField() - user = models.ForeignKey(CustomUser) + user = models.ForeignKey(User) def __str__(self): return self.name diff --git a/projects/serializers.py b/projects/serializers.py new file mode 100755 index 0000000..85866a7 --- /dev/null +++ b/projects/serializers.py @@ -0,0 +1,24 @@ +from rest_framework.serializers import ModelSerializer + +from .models import Project +from specializations.serializers import SpecializationSerializer +from users.serializers import UserSerializer + +class ProjectSerializer(ModelSerializer): + user = UserSerializer() + specialization = SpecializationSerializer() + + class Meta: + model = Project + + fields = ( + 'id', + 'name', + 'price', + 'specialization', + 'text', + 'user', + ) + + def create(self, validated_data): + return Project.objects.create(**validated_data) diff --git a/projects/views.py b/projects/views.py index c83bc6d..aec1b49 100644 --- a/projects/views.py +++ b/projects/views.py @@ -5,7 +5,7 @@ from django.contrib.auth.models import Permission from django.contrib.auth.decorators import permission_required from .models import Project -from users.models import CustomUser +from users.models import User from .forms import ProjectForm diff --git a/specializations/filters.py b/specializations/filters.py new file mode 100755 index 0000000..0febe13 --- /dev/null +++ b/specializations/filters.py @@ -0,0 +1,16 @@ +from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter +from .models import Specialization + +class SpecializationFilterSet(FilterSet): + id = AllLookupsFilter() + children = RelatedFilter('specializations.filters.SpecializationFilterSet') + level = AllLookupsFilter() + lft = AllLookupsFilter() + name = AllLookupsFilter() + parent = RelatedFilter('specializations.filters.SpecializationFilterSet') + projects = RelatedFilter('projects.filters.ProjectFilterSet') + rght = AllLookupsFilter() + tree_id = AllLookupsFilter() + + class Meta: + model = Specialization diff --git a/specializations/migrations/0001_initial.py b/specializations/migrations/0001_initial.py index d13ba5f..1c61ee0 100644 --- a/specializations/migrations/0001_initial.py +++ b/specializations/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.6 on 2016-05-16 14:39 +# Generated by Django 1.9.6 on 2016-05-17 09:03 from __future__ import unicode_literals from django.db import migrations, models diff --git a/specializations/models.py b/specializations/models.py index 711bc2f..66d176e 100644 --- a/specializations/models.py +++ b/specializations/models.py @@ -5,15 +5,11 @@ from mptt.managers import TreeManager class Specialization(MPTTModel): name = models.CharField(max_length=100) parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) - + objects = TreeManager() - + def __str__(self): return self.name - + class MPTTMeta: order_insertion_by = ['name'] - - - - diff --git a/specializations/serializers.py b/specializations/serializers.py new file mode 100755 index 0000000..219527f --- /dev/null +++ b/specializations/serializers.py @@ -0,0 +1,20 @@ +from rest_framework.serializers import ModelSerializer + +from .models import Specialization + + +class SpecializationSerializer(ModelSerializer): + class Meta: + model = Specialization + + fields = ( + 'id', + 'children', + 'level', + 'lft', + 'name', + 'parent', + 'projects', + 'rght', + 'tree_id', + ) diff --git a/templates/_layout.html b/templates/_layout.html new file mode 100644 index 0000000..cec107f --- /dev/null +++ b/templates/_layout.html @@ -0,0 +1,25 @@ +{% load staticfiles %} + + + + + + + + + + + + + + + + +{% block content %}{% endblock %} + + + + + + diff --git a/templates/test.html b/templates/test.html new file mode 100644 index 0000000..96c5bca --- /dev/null +++ b/templates/test.html @@ -0,0 +1,11 @@ +{% extends '_layout.html' %} + +{% load staticfiles %} + +{% block content %} +
+ +
+{% endblock %} diff --git a/users/admin.py b/users/admin.py index d547620..c444238 100644 --- a/users/admin.py +++ b/users/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import CustomUser +from .models import User -admin.site.register(CustomUser) +admin.site.register(User) diff --git a/users/filters.py b/users/filters.py new file mode 100755 index 0000000..82a0753 --- /dev/null +++ b/users/filters.py @@ -0,0 +1,14 @@ +from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter +from .models import User + +class UserFilterSet(FilterSet): + id = AllLookupsFilter() + email = AllLookupsFilter() + first_name = AllLookupsFilter() + is_active = AllLookupsFilter() + is_admin = AllLookupsFilter() + last_name = AllLookupsFilter() + projects = RelatedFilter('projects.filters.ProjectFilterSet') + + class Meta: + model = User diff --git a/users/migrations/0001_initial.py b/users/migrations/0001_initial.py index 926eb98..2ec7900 100644 --- a/users/migrations/0001_initial.py +++ b/users/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.6 on 2016-05-16 14:39 +# Generated by Django 1.9.6 on 2016-05-17 09:03 from __future__ import unicode_literals from django.db import migrations, models @@ -15,14 +15,14 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='CustomUser', + name='User', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('firstname', models.CharField(blank=True, max_length=255)), - ('lastname', models.CharField(blank=True, max_length=255)), + ('first_name', models.CharField(blank=True, max_length=255)), + ('last_name', models.CharField(blank=True, max_length=255)), ('email', models.EmailField(db_index=True, max_length=255, unique=True)), ('is_active', models.BooleanField(default=True)), ('is_admin', models.BooleanField(default=False)), diff --git a/users/models.py b/users/models.py index 89e131a..b292b05 100644 --- a/users/models.py +++ b/users/models.py @@ -3,12 +3,12 @@ from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, Abstra from django.contrib.auth.models import PermissionsMixin -class CustomUserManager(BaseUserManager): +class UserManager(BaseUserManager): def create_user(self, email, password=None): if not email: raise ValueError('Users must have an email address') - user = self.model(email=CustomUserManager.normalize_email(email),) + user = self.model(email=UserManager.normalize_email(email),) user.set_password(password) user.save(using=self._db) return user @@ -30,13 +30,13 @@ class CustomerUserManager(models.Manager): return super(CustomerUserManager, self).get_queryset().filter(groups__name='Заказчик') -class CustomUser(AbstractBaseUser, PermissionsMixin): - firstname = models.CharField(max_length=255, blank=True) - lastname = models.CharField(max_length=255, blank=True) +class User(AbstractBaseUser, PermissionsMixin): + first_name = models.CharField(max_length=255, blank=True) + last_name = models.CharField(max_length=255, blank=True) email = models.EmailField(max_length=255, unique=True, db_index=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) - + @property def is_staff(self): return self.is_admin @@ -48,7 +48,7 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): return self.email def get_full_name(self): - return self.firstname + ' ' + self.lastname + return self.first_name + ' ' + self.last_name # def has_perm(self, perm, obj=None): # perm = perm.split('.')[-1] @@ -68,6 +68,6 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] - objects = CustomUserManager() + objects = UserManager() perform_objects = PerformUserManager() customers_objects = CustomerUserManager() diff --git a/users/serializers.py b/users/serializers.py new file mode 100755 index 0000000..765384c --- /dev/null +++ b/users/serializers.py @@ -0,0 +1,41 @@ +from rest_framework.serializers import ModelSerializer + +from .models import User +from projects.models import Project + + +class UserSerializer(ModelSerializer): + class Meta: + model = User + + fields = ( + 'id', + 'email', + 'first_name', + 'is_active', + 'is_admin', + 'last_name', + 'projects', + ) + + read_only_fields = ( + 'is_active', + 'is_admin', + 'projects', + ) + + def create(self, validated_data): + return User.objects.create(**validated_data) + + # def update(self, inst, validated_data): + # inst.email = validated_data.get('email', inst.email) + # inst.first_name = validated_data.get('first_name', inst.first_name) + # inst.is_active = validated_data.get('is_active', inst.is_active) + # inst.last_name = validated_data.get('last_name', inst.last_name) + # # inst.projects = validated_data.get('projects', inst.projects) + # + # inst.save() + # + # return inst + +# import code; code.interact(local=dict(globals(), **locals())) diff --git a/users/views.py b/users/views.py index c2a1faa..163d282 100644 --- a/users/views.py +++ b/users/views.py @@ -1,25 +1,25 @@ from django.shortcuts import render from django.contrib.auth.models import Group from django.views.generic import ListView, DetailView -from .models import CustomUser +from .models import User class UserListView(ListView): - model = CustomUser + model = User template_name = 'users/users_list.html' context_object_name = 'users' class UserInfoListView(ListView): - model = CustomUser + model = User template_name = 'users/users_info_list.html' def get_context_data(self, **kwargs): context = super(UserInfoListView, self).get_context_data(**kwargs) context['groups'] = Group.objects.all() - context['performers'] = CustomUser.perform_objects.all() - context['customers'] = CustomUser.customers_objects.all() + context['performers'] = User.perform_objects.all() + context['customers'] = User.customers_objects.all() return context class UserDetailView(DetailView): - model = CustomUser \ No newline at end of file + model = User