Integrate SASS/SCSS with Django - django

I want to use SASS/SCSS with Django application.
I followed the link https://bitbucket.org/synic/django-sass.
I installed SASS using sudo pip install sass.
When i run Python manage.py runserver,iam getting error as
'sass' is not a valid tag library: Template library sass not found, tried django.templatetags.sass
Can Anyone help me?!

python sass (pip install sass) https://pypi.python.org/pypi/sass is different
from django-sass (https://bitbucket.org/synic/django-sass)
Download django sass from https://bitbucket.org/synic/django-sass after that install and setup as documented .

Have you first installed sass, the ruby app?
$ apt-get install ruby-sass
You'll know if it's done properlly; as type sass on the command line, does sassy things.
Next, I cloned django-sass (from the other answer):
git clone git#bitbucket.org:synic/django-sass.git
Then navigated to the puled folder and installed it.
$ python setup.py install
Initially the installation crashed out:
IOError: [Errno 2] No such file or directory: 'CHANGES.rst'
So I quickly created the file:
touch CHANGES.rst
and ran the install command again.
no problems.

The django-sass-processor package is a great package that lets you easily integrate SASS/SCSS with Django.
Here's a tutorial on how to set up SASS/SCSS with Django.
I've used the package a few times and have been happy with it.

Here is my DIY out of the box solution
Install Libsass and Watchdog
pip install libsass watchdog
Create an app named core
python manage.py startapp core
core/sass.py
import os
import time
import site
import sass
import threading
from pathlib import Path
from django.apps import apps
from django.conf import settings
from watchdog.observers import Observer
from watchdog.events import FileClosedEvent
def compiler():
packageFolders = [
site.getusersitepackages(),
*[path for path in site.getsitepackages()],
]
staticFolders = settings.STATICFILES_DIRS.copy()
staticFolders += [
os.path.join(app.path, "static") for app in apps.get_app_configs()
]
compileFolders = staticFolders.copy()
for staticFolder in staticFolders:
for packageFolder in packageFolders:
if Path(staticFolder).is_relative_to(packageFolder):
if staticFolder in compileFolders:
compileFolders.remove(staticFolder)
if settings.DEBUG:
def watcher(path):
class Event(FileClosedEvent):
def dispatch(self, event):
filename, extension = os.path.splitext(event.src_path)
if extension == ".scss":
time.sleep(0.5)
for d in compileFolders:
if os.path.isdir(d):
try:
sass.compile(
dirname=(d, d),
output_style="expanded",
include_paths=staticFolders,
)
except sass.CompileError as error:
print(error)
event_handler = Event(path)
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
for d in compileFolders:
if os.path.isdir(d):
try:
sass.compile(
dirname=(d, d),
output_style="expanded",
include_paths=staticFolders,
)
except sass.CompileError as error:
print(error)
thread = threading.Thread(target=watcher, args=(d,), daemon=True)
thread.start()
else:
d = settings.STATIC_ROOT
if os.path.exists(d):
try:
sass.compile(
dirname=(d, d),
output_style="expanded",
include_paths=staticFolders,
)
except sass.CompileError as error:
print(error)
core/apps.py
from django.apps import AppConfig
from core.sass import compiler
class CoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'core'
def ready(self):
compiler()
For more info, djboilerplate is a boilerplate project where I have added this out of the sass feature

Related

Django Utils six for Django 3.1.5

I have a token generator that uses six
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) + six.text_type(user.is_active)
)
account_activation_token = AccountActivationTokenGenerator()
This runs on Django 2.2 but my boss told me to run this on latest 3.1.5. However, six was already depreciated.
I also checked this SO suggestion https://stackoverflow.com/a/65620383/13933721
Saying to do pip install django-six then change from django.utils import six to import six
I did the installation and changes to the code but it gives error message:
ModuleNotFoundError: No module named 'six'
I think I did something wrong or something is missing but I don't know how to proceed.
Here is my pip freeze for reference
asgiref==3.3.1
Django==3.1.5
django-six==1.0.4
djangorestframework==3.12.2
Pillow==8.1.0
pytz==2020.5
sqlparse==0.4.1
EDIT
It should had been pip install six not pip install django-six
pip install six fixed my issue
Offical django page says:
Dont use it or switch to here (https://pypi.org/project/six/)

Django automatically performing the collectstatic command

In my project, I have a main static folder and a sub folder named static. When I make changes in my sub folder named static (which I specified in COLLECTSTATIC_DIRS within the settings file), I save the file and run the collectstatic command.
This successfully saves the changes, however is really inefficient as I am constantly changing css and Javascript files inside my project, which I store as static files.
I browsed the web, and came across a solution named whitenoise, which is a pip package. But this package only works for a short period of time, and after a few times of closing and opening my project folder, it completely stopped working.
Does anybody have another solution to deal with this problem? Thank you.
You can use python-watchdog and write your own Django command:
import time
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
class Command(BaseCommand):
help = "Automatically calls collectstatic when the staticfiles get modified."
def handle(self, *args, **options):
event_handler = CollectstaticEventHandler()
observer = Observer()
for path in settings.STATICFILES_DIRS:
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
finally:
observer.stop()
observer.join()
class CollectstaticEventHandler(FileSystemEventHandler):
def on_moved(self, event):
super().on_moved(event)
self._collectstatic()
def on_created(self, event):
super().on_created(event)
self._collectstatic()
def on_deleted(self, event):
super().on_deleted(event)
self._collectstatic()
def on_modified(self, event):
super().on_modified(event)
self._collectstatic()
def _collectstatic(self):
call_command("collectstatic", interactive=False)
You can use 3rd party solution which doesn't belong to Django to monitor your files and run commands on the files changes.
Take a look at fswatch utility Bash Script - fswatch trigger bash function
How to manage static files "Django-way"
Please check details on https://docs.djangoproject.com/en/3.0/howto/static-files/ what is a Django-way to do it correct :)
First of all set DEBUG = True while working on development.
Then add these lines to your project's urls.py:
from django.conf import settings
from django.views.decorators.cache import cache_control
from django.contrib.staticfiles.views import serve
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
view=cache_control(no_cache=True, must_revalidate=True)(serve))
Here's an example using Python watchfiles and a Django management command.
# Lives in /my_app/manangement/commands/watch_files.py
import time
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand
from watchfiles import watch
class Command(BaseCommand):
help = "Automatically calls collectstatic when the staticfiles get modified."
def handle(self, *args, **options):
print('WATCH_STATIC: Static file watchdog started.')
#for changes in watch([str(x) for x in settings.STATICFILES_DIRS]):
for changes in watch(*settings.STATICFILES_DIRS):
print(f'WATCH_STATIC: {changes}', end='')
call_command("collectstatic", interactive=False)
You can then run the Django management command in the background in whatever script you use to start Django.
python manage.py watch_static &
python manage.py runserver 0.0.0.0:8000

ModuleNotFoundError: No module named 'stripe'

ModuleNotFoundError: No module named 'stripe' Even I Have import into my views.py fle
from django.shortcuts import render
from django.http import HttpResponse,HttpResponseRedirect
from django.conf import settings
import stripe
STRIPE_PUBLISHABLE_KEY1=settings.STRIPE_PUBLISHABLE_KEY
# Create your views here.
def testing(request):
return render(request,"login.html",{'key':STRIPE_PUBLISHABLE_KEY1})
def charge(request): # new
if request.method == 'POST':
charge = stripe.Charge.create(
amount=500,
currency='usd',
description='A Django charge',
source=request.POST['stripeToken']
)
return render(request, 'success.html')
Always Showing Error
NameError at /charge/
name 'stripe' is not defined
May be you haven't install it in your enviroment,Try to install it using
pip install stripe
for more details see documentations https://pypi.org/project/stripe/
Did you install Stripe? if not, try:
pip install stripe
Yet another reason may be that you are using venv but that you installed the module for the wrong version of Python. For example, compare these:
# install to default Python version, which might be, say, 3.10
# ...and then you'll get module not found if you expected to install it to, say, 3.9.
pip install -r requirements.txt
# install the module for 3.9 explicitly
python3.9 -m pip install -r requirements.txt

flask: code in app factory does not get executed

I am using the standard flask app factoty setup as stated here:
http://flask.pocoo.org/docs/1.0/tutorial/factory/
flaskr/init.py
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
print('Hello World')
...
return app
I run this app with:
export FLASK_APP=flaskr
export FLASK_ENV=development
flask run
All very standard. But why is the code print("hello world") never executed?
edit
After reboot of my dev sytem the issue is gone. I am sorry I posted this.
Looks like you named the file init.py instead of __init__.py.
I guess you are using an older version of flask (<1.0).
The newest versions (>1.0) allow to detect automatically the function create_app or make_app (source code) to launch the application from CLI flask command.
You can update the flask package, for example with pip :
pip install --upgrade Flask
or add the following lines at the end of the __init__ file to create the application in an explicit way:
if __name__ == "__main__":
app = create_app()
app.run()

Django equivalent to paster for backend processes

I use pylons in my job, but I'm new to django. I'm making an rss filtering application, and so I'd like to have two backend processes that run on a schedule: one to crawl rss feeds for each user, and another to determine relevance of individual posts relative to users' past preferences. In pylons, I'd just write paster commands to update the db with that data. Is there an equivalent in django? EG is there a way to run the equivalent of python manage.py shell in a non-interactive mode?
I think that's what Custom Management Commands are there for.
Yes, this is actually how I run my cron backup scripts. You just need to load your virtualenv if you're using virtual environments and your project settings.
I hope you can follow this, but after the line # manage.py shell you can write your code just as if you were in manage.py shell
You can import your virtualenv like so:
import site
site.addsitedir(VIRTUALENV_PATH + '/lib/python2.6/site-packages')
You can then add the django project to the path
import sys
sys.path.append(DJANGO_ROOT)
sys.path.append(PROJECT_PATH)
Next you load the django settings and chdir to the django project
import os
from django.core.management import setup_environ
from myproject import settings
setup_environ(settings)
os.chdir(PROJECT_PATH)
After this point your environment will be set just like if you started with manage.py shell
You can then run anything just as if you were in the interactive shell.
from application.models import MyModel
for element in MyModel:
element.delete()
Here is my backup file in full. I've abstracted the process out into functions. This would be named daily_backup and be put into the cron.daily folder to be run daily. You can see how to set up the environment and modify the functionality as needed.
#!/usr/bin/env python
import sys
import os
import site
import logging
from datetime import datetime
PROJECT_NAME = 'myproject'
DJANGO_ROOT = '/var/www/django'
PROJECT_PATH = DJANGO_ROOT + '/' + PROJECT_NAME
VIRTUALENV_PATH = '/var/www/envs/'+ PROJECT_NAME
BACKUP_DIR = '/var/www/backups/%s/daily' % (PROJECT_NAME)
TODAY = datetime.now().strftime('%Y%m%d-%H%M%S')
FILE_NAME = PROJECT_NAME + '_' + TODAY
site.addsitedir(VIRTUALENV_PATH + '/lib/python2.6/site-packages')
sys.path.append(DJANGO_ROOT)
sys.path.append(PROJECT_PATH)
from django.core.management import setup_environ
from myproject import settings
setup_environ(settings)
os.chdir(PROJECT_PATH)
# manage.py shell
from django.conf import settings
logging.basicConfig(level=logging.WARN)
def _setup():
if not os.path.exists(BACKUP_DIR):
logging.debug('Creating backup directory ' + BACKUP_DIR)
os.mkdir(BACKUP_DIR)
os.mkdir(BACKUP_DIR + '/databases')
else:
logging.debug('Using backup directory ' + BACKUP_DIR)
def _remove_old():
logging.debug('Cleaning out old backups')
# keep past 7 days
command = "find %s* -name '%s*' -mtime +7 -exec rm {} \\;" % (BACKUP_DIR, PROJECT_NAME)
os.system(command)
def _create_backup():
logging.debug('Backup database')
if settings.DATABASE_ENGINE == 'mysql':
command = 'mysqldump -u %s --password=%s %s > %s/databases/%s.sql' % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME, BACKUP_DIR, FILE_NAME)
else:
command = '%s/bin/python %s/manage.py dumpdata --indent=4 > %s/databases/%s.json' % (VIRTUALENV_PATH, PROJECT_PATH, BACKUP_DIR, FILE_NAME)
os.system(command)
logging.debug('Backup project')
command = 'tar -czf %s/%s.tgz -C %s %s/' % (BACKUP_DIR, FILE_NAME, DJANGO_ROOT, PROJECT_NAME)
os.system(command)
if __name__ == '__main__':
_setup()
_remove_old()
_create_backup()
Sounds like you need some twod.wsgi in your life: http://packages.python.org/twod.wsgi/