Commit 74162333 authored by Bryan  BRANCOTTE's avatar Bryan BRANCOTTE
Browse files

importing the project

parent 1cf60183
*.pyc
*.swp
.venv
.vscode
venv
.DS_Store
db.sqlite3
*.mo
.idea
\ No newline at end of file
BSD 3-Clause License
Copyright (c) 2019, Hervé MENAGER
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
==========================
Django Basetheme Bootstrap
==========================
A module handling basic fonctionnality needed in django project such as base.html using bootstrap, account settings, preferences management, ...
Detailed documentation is in the "docs" directory.
Quick start
-----------
1. Add "basetheme_bootstrap" to your INSTALLED_APPS setting like this (while not forgetting `crispy_forms`) ::
INSTALLED_APPS = [
...
'crispy_forms',
'basetheme_bootstrap',
]
2. Add the context_processors::
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
'basetheme_bootstrap.context_processors.processors',
],
},
},
]
3. Adjust the configuration::
################################################################################
# django-crispy-forms
################################################################################
CRISPY_TEMPLATE_PACK = 'bootstrap4'
################################################################################
# basetheme_bootstrap
################################################################################
BASETHEME_BOOTSTRAP_TEMPLATE_LOCATION_PROJECT = "test_app_1"
BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED = True
BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_LOCATION_APP = "test_app_1"
BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_NAME = "MyUserPreferences"
################################################################################
3. Include the polls URLconf in your project urls.py like this::
path('', include('basetheme_bootstrap.urls')),
3. Run `python manage.py migrate` to create the UserPreferences model if you decided to have one.
4. Make your templates extends base template from`basetheme_bootstrap`, or even better create your own base.html which extends the one from `basetheme_bootstrap`::
{% extends "basetheme_bootstrap/base4.html" %}
\ No newline at end of file
from django.contrib import admin
from django.contrib.admin.options import get_content_type_for_model
from django.urls import reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext
from basetheme_bootstrap.user_preferences import get_user_preference_class
class ViewOnSiteModelAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',)
}
def __init__(self, model, admin_site):
if callable(getattr(model, "get_absolute_url", None)) and callable(self.view_on_site_in_list):
self.list_display += ('view_on_site_in_list',)
super().__init__(model, admin_site)
def view_on_site_in_list(self, obj):
return format_html(
'<center><a href="' + reverse('admin:view_on_site', kwargs={
'content_type_id': get_content_type_for_model(obj).pk,
'object_id': obj.pk
}) + '"><i class="fa fa-external-link"></i></a><center>')
view_on_site_in_list.short_description = format_html('<center>' + ugettext('View on site') + '<center>')
class UserPreferencesAdmin(admin.ModelAdmin):
ordering = ('user',)
list_display = ['username', ] + [
field.name
for field in (
[]
if get_user_preference_class() is None
else get_user_preference_class()._meta.get_fields()
)
if field.name not in [
"id",
"user",
]
]
list_filter = [
field.name
for field in (
[]
if get_user_preference_class() is None
else get_user_preference_class()._meta.get_fields()
)
if field.name not in [
"id",
"user",
]
]
def username(self, obj):
return mark_safe("<i>default preferences</i>") if obj.user is None else obj.user
username.admin_order_field = 'user__username'
try:
admin.site.register(get_user_preference_class(), UserPreferencesAdmin)
except admin.sites.AlreadyRegistered as e:
pass
except TypeError as e:
pass
from django.apps import AppConfig
class BasethemeBootstrapConfig(AppConfig):
name = 'basetheme_bootstrap'
import logging
from django.core.cache import cache
from basetheme_bootstrap.templatetags.basetheme_bootstrap import basetheme_bootstrap_template_if_not_redefined
from basetheme_bootstrap.user_preferences import get_user_preferences_for_user
logger = logging.getLogger("basetheme_bootstrap")
def processors(request):
return dict(
basetheme_bootstrap_base_template=get_basetheme_bootstrap_base_template(),
pref=get_user_preferences_for_user(None if request.user.is_anonymous else request.user),
)
def get_basetheme_bootstrap_base_template():
r = cache.get(
'basetheme_bootstrap_base_template',
default=None,
)
if r is None:
r = basetheme_bootstrap_template_if_not_redefined("base.html")
cache.set('basetheme_bootstrap_base_template', r, None)
return r
import os
import subprocess
def get_db_ip():
result = subprocess.run([
"docker",
"ps",
"-f",
"name=%s" % get_guessed_container_name(),
"-q",
], stdout=subprocess.PIPE)
ids = result.stdout.decode('utf-8').strip().split('\n')
if len(ids) > 1:
raise Exception("Can't find the DB, too much match")
if len(ids) == 0 or len(ids[0]) == 0:
result = subprocess.run([
"docker",
"ps",
"-f",
"name=_db",
"-q",
], stdout=subprocess.PIPE)
ids = result.stdout.decode('utf-8').strip().split('\n')
if len(ids) > 1:
raise Exception(
"Can't find the DB, couldn't guess container name (tried '%s'), "
"and too much match with '_db'" % get_guessed_container_name())
if len(ids) == 0 or len(ids[0]) == 0:
raise Exception("Can't find the DB")
result = subprocess.run([
"docker",
"inspect",
"-f",
"'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'",
ids[0],
], stdout=subprocess.PIPE)
return result.stdout.decode('utf-8').strip().replace("'", "")
def get_guessed_container_name():
return str(os.path.dirname(__file__).split(os.path.sep)[-2]).lower().replace('-', '') + "_db"
if __name__ == "__main__":
print(get_db_ip())
import itertools
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UsernameField, UserChangeForm
from django.db.models.query_utils import Q
from django.forms import ModelForm
from django.utils.translation import ugettext as _
class UserCreationFormWithMore(UserCreationForm):
class Meta:
model = get_user_model()
fields = ("username", "email", "first_name", "last_name")
field_classes = {'username': UsernameField}
def __init__(self, *args, **kwargs):
super(UserCreationFormWithMore, self).__init__(*args, **kwargs)
self.fields['email'].widget.attrs.update({'required': True})
class MyUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = ("username", "email", "first_name", "last_name", "password")
class UserDeleteForm(ModelForm):
class Meta:
model = get_user_model()
fields = ()
\ No newline at end of file
from django.db import models
# Create your models here.
.fork_me{
font-family: tahoma;
font-size: 20px;
position:fixed;
top:75px;
right:-55px;
display:block;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
background-color:#c5b1e7;
color:black;
padding: 4px 60px 4px 60px;
z-index:99;
}
.dt-buttons{
margin-bottom: 5px;
}
.dt-button{
/*from .btn*/
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
/*from .btn-default*/
text-shadow: 0 1px 0 #fff;
background-image: -webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);
background-image: -o-linear-gradient(top,#fff 0,#e0e0e0 100%);
background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));
background-image: linear-gradient(to bottom,#fff 0,#e0e0e0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
background-repeat: repeat-x;
border-color: #dbdbdb;
border-color: #ccc;
}
.pull-right + .pull-right{
margin-right:4px;
}
\ No newline at end of file
.fork_me{
font-family: tahoma;
font-size: 20px;
position:fixed;
top:75px;
right:-55px;
display:block;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
background-color:#c5b1e7;
color:black;
padding: 4px 60px 4px 60px;
z-index:99;
}
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
body {
padding-top: 3.5rem;
}
.footer {
background-color: #f5f5f5;
}
@media (min-width: 1600px){
.container {
max-width: 1530px;
}
}
@media (min-width: 1920px){
.container {
max-width: 1830px;
}
}
@media (min-width: 2560px){
.container {
max-width: 2490px;
}
}
\ No newline at end of file
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container .multiselect-reset .input-group{width:93%}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.checkbox,.multiselect-container>li>a>label.radio{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}
\ No newline at end of file
/*
* Bootstrap 3 XL CSS Grid
*
* Bootstrap 3 XL CSS Grid addition for big and retina screens coverage
*
* Extends Bootstrap v3 by:
* Adding col-xl (1600+), col-xxl (1920+), col-xxxl (2560+)
* Adding visible and hidden options for all three
* Optionally limiting visible-lg, hidden-lg (1200+) classes to max 1600px
* Optionally increasing container fixed width for all three screen sizes
*
* Copyright 2014 Arnis Puskeiris (apbyte, arnico)
* Licensed under the MIT License
* http://opensource.org/licenses/MIT
*/
/* ==========================================================================
Fix visible-lg and hidden-lg for resolutions over 1600px
Remove if don't want to use
========================================================================== */
@media (min-width: 1600px) {
.visible-lg {
display: none !important;
}
.hidden-lg {
display: block !important;
}
table.hidden-lg {
display: table;
}
tr.hidden-lg {
display: table-row !important;
}
th.hidden-lg,
td.hidden-lg {
display: table-cell !important;
}
}
/* ==========================================================================
Set containers fixed sizes for >1600px, >1920px, >2560px
Remove all if don't want to use big fixed sizes for all blocks
You still can use cols with .container-fluid blocks
========================================================================== */
@media (min-width: 1600px) {
.container {
width: 1530px;
}
}
@media (min-width: 1920px) {
.container {
width: 1830px;
}
}
@media (min-width: 2560px) {
.container {
width: 2490px;
}
}
/* ==========================================================================
col-xl, col-xxl, col-xxxl setup.
Don't remove anything below this line
========================================================================== */
.col-xl-1, .col-xxl-1, .col-xxxl-1, .col-xl-2, .col-xxl-2, .col-md-2, .col-xxxl-2, .col-xl-3, .col-xxl-3, .col-md-3, .col-xxxl-3, .col-xl-4, .col-xxl-4, .col-md-4, .col-xxxl-4, .col-xl-5, .col-xxl-5, .col-md-5, .col-xxxl-5, .col-xl-6, .col-xxl-6, .col-md-6, .col-xxxl-6, .col-xl-7, .col-xxl-7, .col-md-7, .col-xxxl-7, .col-xl-8, .col-xxl-8, .col-md-8, .col-xxxl-8, .col-xl-9, .col-xxl-9, .col-md-9, .col-xxxl-9, .col-xl-10, .col-xxl-100, .col-xxxl-10, .col-xl-11, .col-xxl-111, .col-xxxl-11, .col-xl-12, .col-xxl-122, .col-xxxl-12 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
@media (min-width: 1600px) {
.col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
float: left;
}
.col-xl-12 {
width: 100%;
}
.col-xl-11 {
width: 91.66666667%;
}
.col-xl-10 {
width: 83.33333333%;
}
.col-xl-9 {
width: 75%;
}
.col-xl-8 {
width: 66.66666667%;
}
.col-xl-7 {
width: 58.33333333%;
}
.col-xl-6 {
width: 50%;
}
.col-xl-5 {
width: 41.66666667%;
}
.col-xl-4 {
width: 33.33333333%;
}
.col-xl-3 {
width: 25%;
}
.col-xl-2 {
width: 16.66666667%;
}
.col-xl-1 {
width: 8.33333333%;
}
.col-xl-pull-12 {
right: 100%;
}
.col-xl-pull-11 {
right: 91.66666667%;
}
.col-xl-pull-10 {
right: 83.33333333%;
}
.col-xl-pull-9 {
right: 75%;
}
.col-xl-pull-8 {
right: 66.66666667%;
}
.col-xl-pull-7 {
right: 58.33333333%;
}
.col-xl-pull-6 {
right: 50%;
}
.col-xl-pull-5 {
right: 41.66666667%;
}
.col-xl-pull-4 {
right: 33.33333333%;
}
.col-xl-pull-3 {
right: 25%;
}
.col-xl-pull-2 {
right: 16.66666667%;
}
.col-xl-pull-1 {
right: 8.33333333%;
}
.col-xl-pull-0 {
right: 0;
}
.col-xl-push-12 {
left: 100%;
}
.col-xl-push-11 {
left: 91.66666667%;
}
.col-xl-push-10 {
left: 83.33333333%;
}
.col-xl-push-9 {
left: 75%;
}
.col-xl-push-8 {
left: 66.66666667%;
}
.col-xl-push-7 {
left: 58.33333333%;
}
.col-xl-push-6 {
left: 50%;
}
.col-xl-push-5 {
left: 41.66666667%;
}
.col-xl-push-4 {
left: 33.33333333%;
}
.col-xl-push-3 {
left: 25%;
}
.col-xl-push-2 {
left: 16.66666667%;
}
.col-xl-push-1 {
left: 8.33333333%;
}
.col-xl-push-0 {
left: 0;
}
.col-xl-offset-12 {
margin-left: 100%;
}
.col-xl-offset-11 {
margin-left: 91.66666667%;
}
.col-xl-offset-10 {