pip3 install virtualenvwrapper
mkvirtualenv $ENV && \
workon $ENV
pip install -r requirements.txt
or
# on ubuntu:
sudo apt-get install python3-pip
pip3 install virtualenv
virtualenv .venv && source .venv/bin/activate
#!/usr/bin/env bash
export VIRTUALENVWRAPPER_PYTHON=`which python3`
source `which virtualenvwrapper.sh`
workon $ENV
cd server
./manage.py runserver 0.0.0.0:8000
# Generate a random secret_key
openssl rand -base64 42
# Migrate some stuff
./manage.py makemigrations && ./manage.py migrate
# Create a new developer SU account
./manage.py createsuperuser --username [email protected] --email [email protected]
# Dump Django data out to JSON file, excluding contenttype, admin & auth
./manage.py dumpdata --exclude auth.permission --exclude contenttypes --exclude admin --exclude sessions --indent 2
# Dump Django Apps: accounts & profiles
./manage.py dumpdata accounts profiles --indent 2
# Output Graphviz database diagram (With Django Extensions installed)
./manage.py graph_models app > app.dot
# delete pycache dirs
find . -type d -name __pycache__ -delete
# delete migtations
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
# Inspired by, https://github.com/gothinkster/django-realworld-example-app/blob/master/conduit/apps/core/models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
app_label = 'common'
class TimestampedModel( models.Model ):
created_at = models.DateTimeField(auto_now_add=True,null=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
class Meta:
abstract = True
ordering = ['-created_at', '-updated_at']
Inspired by https://github.com/wsvincent/drfx/blob/master/users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
name = models.CharField(blank=True, max_length=255)
phone_number = models.CharField(blank=True, max_length=255)
def __str__(self):
return self.email
Inspired by https://github.com/gothinkster/django-realworld-example-app/blob/master/conduit/apps/profiles/models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.dispatch import receiver
from django.db.models.signals import post_save
User = get_user_model()
class UserProfile( TimestampedModel ):
user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE, editable=False)
follows = models.ManyToManyField(
'self',
related_name='followed_by',
symmetrical=False,
through='Follows',
blank=True,
)
def follow(self, profile):
"""Follow `profile` if we're not already following `profile`."""
self.follows.add(profile)
def unfollow(self, profile):
"""Unfollow `profile` if we're already following `profile`."""
self.follows.remove(profile)
def is_following(self, profile):
"""Returns True if we're following `profile`; False otherwise."""
return self.follows.filter(pk=profile.pk).exists()
def is_followed_by(self, profile):
"""Returns True if `profile` is following us; False otherwise."""
return self.followed_by.filter(pk=profile.pk).exists()
class Follows( models.Model ):
profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name="+")
follows = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name="+")
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
profile, follows = self.profile, self.follows
return f'Follows( {profile}, {follows} )'
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile = UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
class UserGroup(models.Model):
members = models.ManyToManyField(User, through='UserGroupMembership')
class UserGroupMembership(models.Model):
person = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(UserGroup, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
from django.shortcuts import render
from django.views.generic import CreateView, DetailView, FormView, UpdateView
from django.views.generic.list import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse, reverse_lazy
from django.contrib.auth import get_user_model
User = get_user_model()
from .models import Item
class Create( CreateView ):
model = Item
fields = '__all__'
success_url = reverse_lazy('items')
class Update( UpdateView ):
pass
class Detail( DetailView ):
pass
class Delete( DeleteView ):
pass
class List( ListView ):
pass
"""
<div style="width:250px; height:250px;background-position: center; background-image: url({{user.avatar.url}}); background-size: cover;" class="border border-primary">
"""
from django_resized import ResizedImageField
from uuid import uuid4
import pathlib, os
from django.conf import settings
def custom_location(instance, filename):
user_id = str(instance.uuid)
ext = pathlib.Path( filename ).suffix
filename = f'{user_id}{ext}'
return os.path.join('media','avatars',filename )
class CustomUser(AbstractUser):
uuid = models.UUIDField(default=uuid4)
avatar = ResizedImageField(blank=True,
null=True,
crop=['middle', 'center'],
keep_meta=False,
upload_to=custom_location,
force_format='JPEG')
#models.py
from allauth.account.adapter import DefaultAccountAdapter
class MyAccountAdapter(DefaultAccountAdapter):
def is_open_for_signup(self, request):
return False
#settings.py
ACCOUNT_ADAPTER = 'models.MyAccountAdapter'
from django.db.models.signals import pre_delete
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(pre_delete, sender=Dataset)
def delete_related_journal(sender, instance, **kwargs):
dataset = instance
instance.some_pre_delete_method
@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
user = instance
if created:
profile = UserProfile(user=user, creator=user, first_name=user.first_name, last_name=user.last_name)
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class JsonDataset(DetailView):
def post(self, *args, **kwargs):
"""
curl -d "param1=value1¶m2=value2" -X POST http://localhost:8000/api/v1/test
curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/v1/test
"""
if self.request.headers['Content-Type'].strip() == 'application/json':
params = json.loads( self.request.body )
else:
params = self.request.POST.dict()
return JsonResponse(params, json_dumps_params={'indent': 1} )
class UpdateProfile(UpdateView, LoginRequiredMixin):
model = models.UserProfile
template_name = 'cbv/form.html'
fields = '__all__'
def get_object(self, *args, **kwargs):
profile, _ = self.model.objects.get_or_create(user=self.request.user)
return profile
# Render everthing at /pages from pages directory
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required
def get_html(request, resource):
return render(request, f'pages/{resource}')
# urls.py
urlpatterns = [
path('pages/<path:resource>', views.get_html , name='pages'),
]
# Ingest Posted data
# curl -F 'files=@./requirements.txt' http://localhost:8000/api/ingest
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def ingest_stuff(request):
if request.method == 'GET':
# return render(request, 'upload.html')
return HttpResponse("""<form method="POST" enctype="multipart/form-data"> <input type="file" name="files" multiple> <input type="submit" value="Upload" /></form>""")
# ingest: json, form, data, file
headers = dict( request.headers )
print(request.FILES )
return JsonResponse(dict(headers=headers), safe=False)