Commit 3aca0bf8 authored by luxcem's avatar luxcem

Fresh start for rp

parents
# OSX files
.DS_Store
._*
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*.pyc
.cache
*.sqlite3
.sass-cache
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Local and production settings
project/settings/env.py
# Logs
*.log
node_modules/
# Testing
htmlcov
.coverage
.tox
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class CoreConfig(AppConfig):
name = 'core'
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(ModelBackend):
"""
Authentification backend to allow email
overide AUTHENTICATION_BACKENDS with
fabauth.auth_backends.EmailOrUsernameModelBackend
"""
def authenticate(self, username=None, password=None, **kwargs):
if "@" in username:
kwargs = {"email": username}
else:
kwargs = {"username": username}
try:
user = User.objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
from django.db import models
# Create your models here.
from django.test import TestCase
# Create your tests here.
from django.test import TestCase
from django.test import Client
from django_factory_boy import auth as auth_factories
AUTHENTICATION_BACKENDS = [
# Default
"django.contrib.auth.backends.ModelBackend",
# Email or Username for login
"core.auth_backends.EmailOrUsernameModelBackend"
]
class ApiTest(TestCase):
def setUp(self):
self.client = Client()
self.user = auth_factories.UserFactory(password="dummypassword")
def test_authenticate(self):
with self.settings(AUTHENTICATION_BACKENDS=AUTHENTICATION_BACKENDS):
# username, wrong password
login_status = self.client.login(
username=self.user.username,
password="notthepassword"
)
assert not login_status
# username, correct password
login_status = self.client.login(
username=self.user.username,
password="dummypassword"
)
assert login_status
# email, wrong password
login_status = self.client.login(
username=self.user.email,
password="notthepassowrd"
)
assert not login_status
# email, correct password
login_status = self.client.login(
username=self.user.email,
password="dummypassword"
)
assert login_status
# username, wrong user
login_status = self.client.login(
username="{}-2".format(self.user.username),
password="dummypassword"
)
assert not login_status
# email, wrong user
login_status = self.client.login(
username="{}-2".format(self.user.email),
password="dummypassword"
)
assert not login_status
from django.shortcuts import render
# Create your views here.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User, Permission
from django.utils.translation import ugettext_lazy as _
from userprofile.models import Profile
@admin.register(Permission)
class PermissionAdmin(admin.ModelAdmin):
list_display = ("name", "codename", "content_type")
list_filter = ("content_type",)
class UserProfileInline(admin.StackedInline):
model = Profile
list_display = ("user", "full_name")
extra = 1
max_num = 1
class UserProfileAdmin(UserAdmin):
inlines = [UserProfileInline]
fieldsets = (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("first_name", "last_name", "email")}),
(_("Permissions"), {
"fields": ("is_active", "is_staff", "is_superuser")}),
)
admin.site.unregister(User)
admin.site.register(User, UserProfileAdmin)
from userprofile.models import Profile
from rest_framework import serializers
class ProfileSerializer(serializers.ModelSerializer):
"""A simple profile serializers"""
avatar = serializers.SerializerMethodField()
class Meta:
model = Profile
fields = "__all__"
def get_avatar(self, instance):
if not instance.picture:
return None
return instance.picture.url
from django.apps import AppConfig
class UserprofileConfig(AppConfig):
name = 'userprofile'
import factory
from django_factory_boy import auth as auth_factories
from .models import Profile
class ProfileFactory(factory.django.DjangoModelFactory):
class Meta:
model = Profile
user = factory.SubFactory(auth_factories.UserFactory)
description = factory.Faker("text")
picture = factory.django.ImageField()
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-04-03 15:05
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.CharField(blank=True, max_length=200, null=True)),
('picture', models.ImageField(blank=True, null=True, upload_to='uploads/users/%Y/%m/%d')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'User',
},
),
]
from imagekit.models import ImageSpecField
from pilkit.processors import ResizeToFill
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext as _
class Profile(models.Model):
"""
Extends `django.contrib.auth.models.User` with additional fields
"""
#: OneToOneField to ``django.contrib.auth.models.User``
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name="profile"
)
#: User description
description = models.CharField(max_length=200, null=True, blank=True)
#: User avatar
picture = models.ImageField(
upload_to="uploads/users/%Y/%m/%d",
null=True,
blank=True
)
#: 50x50 thumbnail of user picture
picture_t = ImageSpecField(
source="picture",
processors=[ResizeToFill(50, 50)],
format="jpeg",
)
class Meta:
verbose_name = _("User")
app_label = "userprofile"
def __str__(self):
"""Returns user full name"""
return self.username
def delete(self, *args, **kwargs):
"""Deletes ``django.contrib.auth.models.User`` and
this profile"""
self.user.delete()
return super().delete(*args, **kwargs)
@property
def slug(self):
"""
Returns slug version of user.username
"""
return slugify(self.user.username)
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from userprofile.apps import UserprofileConfig
from userprofile.models import Profile
from userprofile.factories import ProfileFactory
def test_init():
assert UserprofileConfig.name == "userprofile"
def test_profile():
profile = ProfileFactory()
assert type(profile.user) == User
assert type(profile) == Profile
assert type(profile.full_name) == str
assert profile.slug == slugify(profile.user.username)
assert type(profile.identity) == str
assert str(profile) == profile.full_name
profile.delete()
from django.shortcuts import render
# Create your views here.
import os
import pytest
import django
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
@pytest.fixture(autouse=True)
def enable_db_access_for_all_tests(db):
"""Adds access to db to all tests"""
def pytest_configure():
settings.DEBUG = False
django.setup()
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
"""
Import settings from all files in settings directory
"""
from .env import * # noqa
from .base import * # noqa
from .apps import * # noqa
from .auth import * # noqa
from .api import * # noqa
from .static import * # noqa
from .i18n import * # noqa
"""
django-rest-framework and api related settings
"""
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": ("rest_framework.pagination."
"PageNumberPagination"),
"PAGE_SIZE": 20,
}
"""
Django installed apps
"""
from .env import DEBUG
DJANGO_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.contenttypes",
]
CONTRIB_APPS = [
"django_extensions", # http://django-extensions.readthedocs.io/
"rest_framework", # http://www.django-rest-framework.org/
# https://github.com/philipn/django-rest-framework-filters
# "rest_framework_filters",
]
if DEBUG:
CONTRIB_APPS.append(
'debug_toolbar', # https://django-debug-toolbar.readthedocs.io/
)
PROJECT_APPS = [
"userprofile",
"core"
]
INSTALLED_APPS = DJANGO_APPS + CONTRIB_APPS + PROJECT_APPS
"""
User registration and login related settings
"""
AUTH_USER_MODEL = "auth.User"
EXTENDED_USER_MODEL = "userprofile.Profile"
LOGIN_URL = "login"
AUTHENTICATION_BACKENDS = [
# Default
"django.contrib.auth.backends.ModelBackend",
# Email or Username for login
"core.auth_backends.EmailOrUsernameModelBackend",
]
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": ("django.contrib.auth.password_validation."
"UserAttributeSimilarityValidator"),
},
{
"NAME": ("django.contrib.auth.password_validation."
"MinimumLengthValidator"),
},
{
"NAME": ("django.contrib.auth.password_validation."
"CommonPasswordValidator"),
},
{
"NAME": ("django.contrib.auth.password_validation."
"NumericPasswordValidator"),
},
]
"""
Django settings for rp_new project.
"""
import os
import sys
from .env import DEBUG
BASE_DIR = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
)
# Adds apps to path
APPS_DIR = os.path.realpath(os.path.join(BASE_DIR, "apps"))
sys.path.append(APPS_DIR)
ALLOWED_HOSTS = []
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
if DEBUG:
MIDDLEWARE.append(
"debug_toolbar.middleware.DebugToolbarMiddleware"
)
ROOT_URLCONF = "project.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
"builtins": [
# Provide {% static %}
"django.contrib.staticfiles.templatetags.staticfiles",
# Provide {% trans %}
"django.templatetags.i18n",
# Provide {% permission %}
"permission.templatetags.permissionif"
]
},
},
]
WSGI_APPLICATION = "project.wsgi.application"
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
"""
Internationalization and localization settings
See https://docs.djangoproject.com/en/1.10/topics/i18n/ for refs
"""
import os
from .base import BASE_DIR
# TODO : use en in backend and user lc in frontend
LANGUAGE_CODE = "en-US"
# TODO : use UTC in backend and use user tz in frontend
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Adds languages here
LANGUAGES = (
("en", "English"),
("fr", "French"),
)
LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")]
"""
Static files related settings
See https://docs.djangoproject.com/en/1.10/howto/static-files/ for refs
"""
import os
from .base import BASE_DIR
# Url to get static files
STATIC_URL = "/static/"
# Directory of static files (used by collectstatic)
STATIC_ROOT = os.path.join(BASE_DIR, "static", "static_root")
# Additionaly to apps/static dirs, files in staticfiles_dirs will be copied
# by collectstatic
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static", "build"),
)
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "static", "media")
"""
rp_new URL Configuration
"""
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r"^admin/", admin.site.urls),
]
"""
WSGI config for rp_new project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
application = get_wsgi_application()
[pytest]
DJANGO_SETTINGS_MODULE = project.settings
python_files = tests.py test_*.py *_tests.py
\ No newline at end of file
django-debug-toolbar
tox
pytest
pytest-cov
pytest-django
# Fixture
factory-boy
django-factory-boy
# Code style
jedi
importmagic
autopep8
flake8
pep8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment