@Jasper_Holton's صورة الملف الشخصي

How to Upload a Webm Video From a Webcam to a Django Site Uploading a WebM video has many purposes including live chat, live video, verification, and other purposes. This software is all over the internet, and it is very useful for verification, entertainment, security, media, hobby, and other purposes. I hope you find this code useful and deploy it yourself, expanding on my ideas to create your own products. I'll explain how to implement basic security, which happens quickly and efficiently without very much cost.

# The models
# app/models.py
def get_file_path(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (uuid.uuid4(), ext)
    return os.path.join('video/', filename)

class Camera(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='camera')
    frame = models.FileField(upload_to=get_file_path, null=True, blank=True)
    last_frame = models.DateTimeField(default=timezone.now)
# The views
# app/views.py
@login_required
@csrf_exempt
def video(request):
    cameras = VideoCamera.objects.filter(user=request.user)
    camera = None
    if cameras.count() == 0:
        camera = VideoCamera.objects.create(user=request.user)
        camera.save()
    else:
        camera = cameras.first()
    if request.method == 'POST':
        try:
            form = CameraForm(request.POST, request.FILES, instance=camera)
            camera = form.save()
        except:
            print(traceback.format_exc())
        return HttpResponse(status=200)
    return render(request, 'app/video.html', {'title': 'Video', 'form': CameraForm()})
# The forms
# app/forms.py
from django import forms
from app.models import Camera

class CameraForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(CameraForm, self).__init__(*args, **kwargs)
    class Meta:
        model = Camera
        fields = ('frame',)


{% extends 'base.html' %}
{% block content %}
<div id="container">
<video autoplay="true" muted="true" id="video-element" width="100%"></video>
<form method="POST" enctype="multipart/form-data" id="live-form" style="position: absolute; display: none; visibility: hidden;">
{{ form }}
</form>
</div>
{% endblock %}
// The javascript
// templates/video.js
var form = document.getElementById('live-form');
var scale = 0.2;
var width = 1920 * scale;
var height = 1070 * scale
var video = document.getElementById('video-element');
var data;
var mediaRecorder;
var mediaChunks = [];
const VIDEO_INTERVAL = 5000; // The length of each packet to send, ideally more than 5000 ms (5 seconds)
function capture() {
    mediaRecorder.stop(); // Stop to recod data
}
function startup() {
    navigator.mediaDevices.getUserMedia({
            video: {
                width: {
                    ideal: width
                },
                height: {
                    ideal: height
                }
            },
            audio: true
        })
        .then(function(stream) {
            video.srcObject = stream;
            video.play();
            mediaRecorder = new MediaRecorder(stream);
            mediaRecorder.addEventListener("dataavailable", event => {
                mediaChunks.push(event.data);
                var mediaData = clone(mediaChunks);
                var file = new Blob(mediaData, {
                    'type': 'video/webm'
                });
                mediaChunks = [];
                mediaRecorder.start();
                var formdata = new FormData(form);
                formdata.append('frame', new File([file], 'frame.webm'));
                $.ajax({
                    url: window.location.href,
                    type: "POST",
                    data: formdata,
                    processData: false,
                    contentType: false,
                }).done(function(respond) {
                    console.log(respond);
                    console.log("Sent frame");
                });
            });
            setTimeout(function() {
                setInterval(capture, VIDEO_INTERVAL);
            }, 5000);
            mediaRecorder.start();
        }).catch(function(err) {
            console.log("An error occurred: " + err);
        });
}
startup();
This is all it takes to upload a WebM video from your webcam. Django sites are ideal for this, as they support large objects and can index them easily. Please be cautious with this however, and do use APIs to make sure your uploaded content is safe. I use an API from SightEngine.com which contains a workflow to remove video I don't want on my site. This is what it looks like:
# The API call
# live/apis.py
import requests
import json

params = {
  'workflow': 'wfl_00000000000000000US',
  'api_user': '000000000',
  'api_secret': '000000000000000000'
}

def is_safe(video_path):
    files = {'media': open(video_path, 'rb')}
    r = requests.post('https://api.sightengine.com/1.0/video/check-workflow-sync.json', files=files, data=params)
    output = json.loads(r.text)
    if output['status'] == 'failure' or output['summary']['action'] == 'reject':
        return False
    return True
The next part is a save call in the models.py.
# And the models.py save call
...
    def save(self, *args, **kwargs):
        last_frame = self.frame
        super(VideoCamera, self).save(*args, **kwargs)
        if self.frame and self.frame != last_frame and not is_safe(self.frame.path):
            self.frame = None
            self.save()
Creating a workflow on SightEngine allows you to filter out offensive content, celebrities, children, and even alcohol or drugs. This keeps sites safer when uploading videos. I also recommend using facial recognition in order to verify which users are uploading what content. This is important when keeping records of access for verification. How much does it cost? Running a server that can cache video can be expensive if you have a lot of video to cache, but experimenting is quite inexpensive, less than $10 a month for the server. The API, SightEngine is free for 500 API calls per day and 2000 per month, but this means only about 42 minutes of video per day with 5-second video segments. It is still worthwhile to keep your site secure, as, at $29 per month, you get 10,000 API calls running about 833 hours or 14 full days (28 12-hour days). I hope this code is useful to you. I appreciate your feedback if you are willing to comment or like, you can log in with your face!


@Jasper_Holton's صورة الملف الشخصي

How to identify and recognize faces using python with no APIs I use the below code to implement a login with face function on Uglek. The code works by assigning a user a face ID when they upload a face to their profile or go to log in, and then retrieving their account by image using the face ID. Here is the code

# face/face.py
from django.contrib.auth.models import User
import uuid
from .models import Face
import face_recognition

NUM_FACES = 9

def get_face_id(image_path):
    image = face_recognition.load_image_file(image_path)
    face_locations = face_recognition.face_locations(image)
    if len(face_locations) > 1 or len(face_locations) < 1:
        return False

    for user in User.objects.filter(profile__enable_facial_recognition=True):
        known_image = face_recognition.load_image_file(user.profile.face.path)
        unknown_image = image
        user_encoding = face_recognition.face_encodings(known_image)[0]
        user_encodings = list()
        user_encodings.append(user_encoding)
        user_faces = Face.objects.filter(user=user).order_by('-timestamp')
        for face in user_faces:
            if open(face.image.path,"rb").read() == open(image_path,"rb").read():
                return False
        if user_faces.count() > NUM_FACES:
            user_faces = user_faces[:NUM_FACES]
        for face in user_faces:
            image = face_recognition.load_image_file(face.image.path)
            image_encoding = face_recognition.face_encodings(image)[0]
            user_encodings.append(image_encoding)
        unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
        results = face_recognition.compare_faces(user_encodings, unknown_encoding)
        if results[0]:
            return user.profile.uuid
    return str(uuid.uuid4())
In action, the code looks like get_face_id(User.objects.get(id=1).face.path) in testing. This gets my face ID from the face uploaded to my profile. To get a face ID of a logging in user, I save a face form with a face object and then call get_face_id(face.image.path) to query the user instance and redirect to their authentication URL. This works well. I hope this is useful to you. For more information, see the GitHub below: github.com/ageitgey/face_recognition


@Jasper_Holton's صورة الملف الشخصي

How to Identify Unique Faces with the Microsoft Azure Face API Using the Microsoft Azure Face API, you can assign unique faces a UUID and identify them for use in login, verification, or any other purpose. The following code accepts an image of a single face and returns a unique UUID representing that face. This has a huge application potential in internet security and could make some sites and businesses much more secure, by uniquely attributing faces to profiles within the apps or security solutions. Using the face API with Microsoft Azure is free for basic use, and isn't expensive otherwise. To install python modules for this code, run $ pip install --upgrade azure-cognitiveservices-vision-face $ pip install --upgrade Pillow The code is as follows.

# face/face.py
import asyncio
import io
import glob
import os
import sys
import time
import uuid
import requests
from urllib.parse import urlparse
from io import BytesIO
from PIL import Image, ImageDraw
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.face.models import TrainingStatusType, Person, QualityForRecognition
import json

# This key will serve all examples in this document.
KEY = "000000000000000000000000000000"
# This endpoint will be used in all examples in this quickstart.
ENDPOINT = "https://endpoint.api.cognitive.microsoft.com/"

PERSON_GROUP_ID = str("group") # assign a random ID (or name it anything)

def get_face_id(single_face_image_url):
    # Create an authenticated FaceClient.
    face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))
    # Detect a face in an image that contains a single face
    single_image_name = os.path.basename(single_face_image_url)
    # We use detection model 3 to get better performance.
    face_ids = []
    # We use detection model 3 to get better performance, recognition model 4 to support quality for recognition attribute.
    faces = face_client.face.detect_with_url(single_face_image_url, detection_model='detection_03') #, recognition_model='recognition_04', return_face_attributes=['qualityForRecognition'])
    # Remove this line after initial call with first face (or you will get an error on the next call)
    face_client.person_group.create(person_group_id=PERSON_GROUP_ID, name=PERSON_GROUP_ID)

    for face in faces: # Add faces in the photo to a list
        face_ids.append(face.face_id)

    if len(faces) > 1: # Return if there are too many faces
        return False

    results = None
    try:
        results = face_client.face.identify(face_ids, PERSON_GROUP_ID) # Identify the face
    except:
        results = None
    if not results: # Add the face if they are not identified
        p = face_client.person_group_person.create(PERSON_GROUP_ID, uuid.uuid4()) # Identify them with a UUID
        face_client.person_group_person.add_face_from_url(PERSON_GROUP_ID, p.person_id, single_face_image_url)
        face_client.person_group.train(PERSON_GROUP_ID) # Training
        while (True):
            training_status = face_client.person_group.get_training_status(PERSON_GROUP_ID)
            print("Training status: {}.".format(training_status.status))
            print()
            if (training_status.status is TrainingStatusType.succeeded):
                break
            elif (training_status.status is TrainingStatusType.failed):
                sys.exit('Training the person group has failed.')
            time.sleep(5)
        results = face_client.face.identify(face_ids, PERSON_GROUP_ID)
    if results and len(results) > 0: # Load their UUID
        res = json.loads(str(results[0].candidates[0]).replace('\'',"\""))['person_id']
        print(res)
        return res # Return their UUID
    return False # Or return false to indicate that no face was recognized.

f = 'uglek.com/media/face/1b195bf5-8150-4f84-931d-ef0f2a464d06.png'
print(get_face_id(f)) # Identify a face from this image
Using this code, you can call get_face_id(face_url) to get an ID from any face. Your face ID will be unique to each user, so you can cache it on a profile and use it to retrieve a profile. This is the way the "Login with your face" option works on Uglek. I hope you enjoy this code, and it is useful to you. Feel free to use it as you will, but be sure to install your own API keys from Azure.com. Thank you!


@Jasper_Holton's صورة الملف الشخصي

How to Generate a String from a Number in Python I use the following code to generate a string from a number under 1000. It is using simple arrays and if statements to generate a compound number as a string.


import math
n = ['one','two','three','four','five', 'six', 'seven', 'eight', 'nine', 'ten']
tn = ['eleven','twelve','thir','four','fif','six','seven','eigh','nine']
nn = ['ten','twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety']
def number_to_string(num):
    if not isinstance(num, int):
        num = int(num) if num != '' else 'done'
    if num == 'done':
        return ''
    if num == 0:
        return ''
    if num < 11:
        return n[num-1]
    if num < 20:
        if num < 13:
            return tn[num-11]
        return tn[num-11] + 'teen'
    if num < 100:
        extra = '-'+n[num%10-1]
        if num%10 == 0:
            extra = ''
        return nn[math.floor(num/10)-1]+extra
    if num < 1000:
        extra = '-'+n[num%10-1]
        if num%10 == 0:
            extra = ''
        snum = str(num)
        return n[math.floor(num/100)-1]+'-hundred'+ ('-' if number_to_string(int(snum[1:])) != '' else '') + number_to_string(int(snum[1:]))
    if num < 10000:
        snum = str(num)
        return number_to_string(int(snum[:1])) + '-thousand' + ('-' if number_to_string(int(snum[1:])) != '' else '') +number_to_string(int(snum[1:]))
    if num < 100000:
        snum = str(num)
        return number_to_string(int(snum[:2])) + '-thousand' + ('-' if number_to_string(int(snum[2:])) != '' else '') + number_to_string(int(snum[2:]))
    if num < 1000000:
        snum = str(num)
        return number_to_string(snum[:len(snum) - 3]) + '-thousand' + ('-' if number_to_string(snum[len(snum)-3:]) != '' else '') + number_to_string(snum[len(snum)-3:])    
    if num < 1000000000:
        snum = str(num)
        return number_to_string(snum[:len(snum) - 6]) + '-million' + ('-' if number_to_string(snum[len(snum)-6:]) != '' else '') + number_to_string(snum[len(snum)-6:])
    return 'number too large to compute!'

#for x in range(1,100000):
#    print(number_to_string(x))
print(number_to_string(999999999))
This returns a compound string number, "nine-hundred-ninety-nine-million-nine-hundred-ninety-nine-thousand-nine-hundred-ninety-nine".


@Jasper_Holton's صورة الملف الشخصي

رسم جافا سكريبت - كوب قهوة أنشأ هذا الرسم البسيط برمز اليوم كصورة منتج للأزرار الجديدة. إنه رسم لكوب قهوة ، مصنوع باستخدام أشكال بيضاوية ومستطيلات. الكود الذي يرسمه أدناه. * (جافا سكريبت) * الوظيفة init () { var stage = new createjs.Stage ("coffee") ؛ var background = new createjs.Shape () ؛ var yoffset = 40 ، background.graphics.beginFill ("DeepSkyBlue"). drawRect (0، 0، 500، 500) ؛ stage.addChild (الخلفية) ، var Circle = new createjs.Shape () ؛ Circle.graphics.beginFill ("أبيض"). drawEllipse (10 + 300 + yoffset، 250-150، 120، 300) ؛ stage.addChild (دائرة) ؛ var Circle3 = new createjs.Shape () ؛ Circle3.graphics.beginFill ("DeepSkyBlue"). drawEllipse (370، 90 + yoffset، 70، 240) ؛ stage.addChild (دائرة 3) ، var mug = new createjs.Shape () ؛ mug.graphics.beginFill ("أبيض"). drawRect (100 ، 60 + yoffset ، 300 ، 300) ؛ stage.addChild (كوب) ؛ var Circle = new createjs.Shape () ؛ Circle.graphics.beginFill ("أبيض"). drawEllipse (250-150 ، 10 + yoffset ، 300 ، 100) ؛ stage.addChild (دائرة) ؛ var Circle2 = new createjs.Shape () ؛ Circle2.graphics.beginFill ("بني"). drawEllipse (250-130 ، 30 + yoffset ، 260 ، 60) ؛ stage.addChild (دائرة 2) ؛ var Circle4 = new createjs.Shape () ؛ Circle4.graphics.beginFill ("أبيض"). drawEllipse (250 - 150 ، 10 + 300 + yoffset، 300، 100) ؛ stage.addChild (دائرة 4) ، stage.update () ، } ***

عرض الصورة من وظيفة عن طريق @Jasper_Holton

@Jasper_Holton, يحب هذا،

@Jasper_Holton's صورة الملف الشخصي

كيفية عمل سمة ديناميكية سهلة القراءة استنادًا إلى شروق الشمس وغروبها يتيح لي هذا الرمز عرض الصفحات تلقائيًا إما في الوضع الفاتح أو الغامق (بنمط فاتح أو غامق) اعتمادًا على ما إذا كانت الشمس فوق. أنا أستعلم عن معلومات الموقع والمنطقة الزمنية باستخدام واجهة برمجة التطبيقات. هذه طريقة رائعة لتسهيل رؤية موقع ما في الليل. قد يكون من الصعب بعض الشيء استخدام صفحة ويب تحتوي على الكثير من المساحات الفارغة البيضاء في الليل ، لذلك من الأفضل أن يكون لديك معالج سياق يجعل الموقع أسهل في القراءة ليلاً. * (python) * # app / Context_processors.py استيراد pytz من الاستيراد النجمي LocationInfo من astral.sun استيراد الشمس معالج السياق (Context_data) tz = request.user.profile. ] = False # أو بخلاف ذلك اجعله خفيفًا إرجاع Context_data # users / middleware.py def simple_middleware (get_response): # واحد - التكوين والتهيئة الوقت. البرمجيات الوسيطة (طلب): المستخدم = get_user_model () if request.user.is_authenticated and hasattr (request.user، 'profile'): مستخدم = get_object_or_404 (User، pkBesole002request.user.pk) # قم بتحديث وقت الزيارة الأخير بعد انتهاء معالجة الطلب. last_ip = request.user.profile.ip request.user.profile.ip = get_client_ip (طلب) if request.user.profile.ip! = last_ip: request.user.profile.timezone = get_timezone (request.user.profile.


@Jasper_Holton's صورة الملف الشخصي

إصلاح صوتي مفيد لإطارات Iframes باستخدام jQuery هذه هي الطريقة التي يعمل بها على إيقاف الصوت مؤقتًا في المستند مع إطارات مضمنة بحيث لا يتم تشغيل الصوت أكثر من مرة في المستند. يغير هذا الإصلاح الموقع لإصلاح تشغيل الصوت المزدوج في إطارات مضمنة متعددة. يتم تضمين هذا الرمز في كل إطار iframe وفي المستند الرئيسي.

 $ (function () {
 $ ("audio"). on ("play"، function () {// عند تشغيل كل صوت في المستند الأساسي 
 $ ("audio"، window.parent.document) .not (this) .each (الوظيفة (الفهرس ، الصوت) {// احصل على كل صوت غير هذا 
 audio.pause ( )؛ // Pause 
})؛ 
 التشغيل = هذا؛ // احفظ الصوت الجاري تشغيله 
 $ ("iframe"، window.parent.document). كل (وظيفة (فهرس ، iframe) {// احصل على جميع إطارات iframe في المستند الأصلي 
 $ (iframe) .contents (). find ("audio"). not (play). every (function (index، audio ) {// تصفية الأصوات التي لا يجب تشغيلها (وليس الصوت الذي نقرنا عليه) 
 audio.pause () ؛ // إيقاف الصوت 
}) ؛ 
}) ؛ 
}) ، 
}) ، 
 
يوقف هذا الرمز البسيط عناصر الصوت على موقعي مؤقتًا حيث يتم تشغيل عنصر جديد. يمكن استخدامه لمنع تشغيل الأصوات المكررة ، ويتم تشغيله على جميع ملفات الصوت وإطارات iframe بحيث يمكن استخدامه في أي مستند. يجب أن يتم دمجها في المستند الأصلي وكل إطار iframe لصفحة التمرير. كل (وظيفة (فهرس ، صوت) {// تصفية الصوتيات التي يجب ألا يتم تشغيلها (ليست تلك التي نقرنا عليها) audio.pause () ؛ // إيقاف الصوت }) ؛ }) ، }) ، }) ، *** يوقف هذا الرمز البسيط عناصر الصوت على موقعي مؤقتًا حيث يتم تشغيل عنصر جديد. يمكن استخدامه لمنع تشغيل الأصوات المكررة ، ويتم تشغيله على جميع ملفات الصوت وإطارات iframe بحيث يمكن استخدامه في أي مستند. يجب أن يتم دمجها في المستند الأصلي وكل إطار iframe لصفحة التمرير. كل (وظيفة (فهرس ، صوت) {// تصفية الصوتيات التي يجب ألا يتم تشغيلها (ليست تلك التي نقرنا عليها) audio.pause () ؛ // إيقاف الصوت }) ؛ }) ، }) ، }) ، *** يوقف هذا الرمز البسيط عناصر الصوت على موقعي مؤقتًا حيث يتم تشغيل عنصر جديد. يمكن استخدامه لمنع تشغيل الأصوات المكررة ، ويتم تشغيله على جميع ملفات الصوت وإطارات iframe بحيث يمكن استخدامه في أي مستند. يجب أن يتم دمجها في المستند الأصلي وكل إطار iframe لصفحة التمرير. *** يوقف هذا الرمز البسيط عناصر الصوت على موقعي مؤقتًا حيث يتم تشغيل عنصر جديد. يمكن استخدامه لمنع تشغيل الأصوات المكررة ، ويتم تشغيله على جميع ملفات الصوت وإطارات iframe بحيث يمكن استخدامه في أي مستند. يجب أن يتم دمجها في المستند الأصلي وكل إطار iframe لصفحة التمرير. *** يوقف هذا الرمز البسيط عناصر الصوت على موقعي مؤقتًا حيث يتم تشغيل عنصر جديد. يمكن استخدامه لمنع تشغيل الأصوات المكررة ، ويتم تشغيله على جميع ملفات الصوت وإطارات iframe بحيث يمكن استخدامه في أي مستند. يجب أن يتم دمجها في المستند الأصلي وكل إطار iframe لصفحة التمرير.


@Jasper_Holton, يحب هذا،

@Jasper_Holton's صورة الملف الشخصي

معالجة الأخطاء المطولة باستخدام برمجية Django الوسيطة هذه طريقة بسيطة للتعامل مع الأخطاء بإسهاب باستخدام برمجيات Django الوسيطة. باستخدام هذه البرامج الوسيطة ، يمكنك عرض عمليات تتبع الأخطاء لصفحات HTML المخصصة ، بدلاً من استخدام صفحات خطأ وضع تصحيح أخطاء Django. هنا كيف يعمل الكود. أولاً ، بعض البرامج الوسيطة للحصول على الخطأ الحالي في عرض معالج الأخطاء.

 # app / middleware.py 
 من سلاسل الاستيراد المحلية 
 استيراد traceback 
 من django.utils.deprecation import MiddlewareMixin 
 
 _ error = local () # تخزين الخطأ في محلي 
 
 class ExceptionVerboseMiddleware (MiddlewareMixin): 
 def process_exception (ذاتي ، طلب ، استثناء): # معالجة الاستثناء 
 _error.value = traceback. format_exc () # قم بتخزين تتبع المكدس من traceback 
 
 def get_current_exception (): # قم بإرجاع الخطأ 
 حاول: 
 return _error.value 
 باستثناء AttributeError: 
 عودة بلا 
 
في طرق العرض ، قم بإضافة استدعاء إلى البرنامج الوسيط للحصول على الاستثناء.
 # app / views.py 
 معالج التعريف 500 (الطلب): 
 البيانات = {'title': 'Error 500'، 'error': get_current_exception ( )} # ضع الخطأ في السياق ، حتى نتمكن من عرضه على القالب. 
 عرض الإرجاع (الطلب ، 'blog / 500.html' ، البيانات) 
 
قم بتضمين هذه البرامج الوسيطة في ملف settings.py.
 # project / settings.py 
 MIDDLEWARE = ​​[
 '...' ، 
 'التطبيق. middleware.ExceptionVerboseMiddleware '، 
' ... '
] 
 
وأخيرًا ، أضف هذا السطر إلى urls.py لمشاريعك [= NEWLINE = ]
 # project / urls.py 
 handler500 = 'blog.views.handler500' 
 
الآن ، ما عليك سوى إضافة علامة ،
 {{error}} 
، لتقديم الخطأ إلى صفحة الخطأ 500. هذا كل ما يتطلبه الأمر لإعداد صفحة معالجة الأخطاء المطولة في Django.


@Jasper_Holton's صورة الملف الشخصي

How to Create an Infinitely Scrolling Django View Creating a pseudo-infinitely scrolling page for a Django site is fairly easy. It involves creating a main page that renders the first posts, a secondary page that renders more posts according to a page number, and using some basic JavaScript to load in more posts when the user scrolls to the bottom of the page. I created two views to handle the backend code.

# This view renders a scrollable page.
@vary_on_cookie
def scroll(request):
    posts = Post.objects.filter(public=True).order_by('date_posted') # Get the posts for the first page
    p = Paginator(posts, 10) # Paginate them
    if request.user.is_authenticated: # Mark viewership if users are logged in
        for post in p.page(p.num_pages):
            if not post.viewers.filter(id=request.user.id).exists():
                post.viewers.add(request.user)
    context = { # Render the posts
        'posts': p.page(p.num_pages),
        'count': p.count,
        'page_obj': p.get_page(p.num_pages),
        'title': 'Scroll Posts',
        'description': 'Scroll and see all the posts on Uglek here. This is the front page of Uglek.' + basedescription,
        'dontshowsidebar': True,
        'full': True,
        'num_pages': p.num_pages,
    }
    response = render(request, 'blog/scroll.html', context)
    if request.user.is_authenticated:
        patch_cache_control(response, private=True) # Render private page
    return response

# This view is simple. It renders the posts for each page as we scroll through them.
@vary_on_cookie
def scroll_page(request):
    posts = Post.objects.filter(public=True).order_by('date_posted') # Get posts
    p = Paginator(posts, 10) # Paginate them
    page = p.num_pages - 1
    if(request.GET.get('page', '') != ''): # Get the page from the querystring
        page = int(request.GET.get('page', ''))
    if request.user.is_authenticated: # Mark viewership if the user is logged in
        for post in p.page(page):
            if not post.viewers.filter(id=request.user.id).exists():
                post.viewers.add(request.user)
    context = {
        'posts': p.page(page), # Render the posts
        'count': p.count,
        'page_obj': p.get_page(page),
    }
    response = render(request, 'blog/scrollpage.html', context)
    if request.user.is_authenticated:
        patch_cache_control(response, private=True) # Render private page
    return response
The javascript is pretty simple too, we just load in new content every time the window is scrolled close to the bottom.
var page = {{ num_pages }};
$(window).scroll(function() { // On scroll
    if ($(window).scrollTop() + $(window).height() > $(document).height() - 5000) {
        loadNext(); // Load new content
    }
});
loadNext(); // Start by loading
var loading = false; // Keep track of whether we are loading
function loadNext() {
    if (!loading && page > 1) { // If we are not loading already and there is another page
        loading = true; // Mark that we are loading
        page = page - 1; // Decrement the page (to load the next page)
        var scrollContainer = document.getElementById("scroll-container"); // Get the container
        const urlParams = new URLSearchParams(window.location.search);
        var lang = '';
        if (urlParams.get('lang') != null) {
            lang = "&lang=" + urlParams.get('lang'); // Get the language
        }
        // Make a request to the next page with the language
        const Http = new XMLHttpRequest(); 
        const url = "https://uglek.com/scroll/page/?page=" + page + lang;
        Http.responseType = 'text';
        Http.onload = function() {
            if (Http.readyState === Http.DONE) {
                scrollContainer.insertAdjacentHTML("beforeend", Http.responseText);
                loading = false;
            }
        };
        Http.open("GET", url, true);
        Http.send(null); // Send the request
    }
}
The templates are fairly self-explanatory, you just need to render the first posts in the main template, scroll.html, and more posts in scrollpage.html. You'll need to render the pages in an iframe in order for some scripts and products like Google AdSense to work, this is easy to do as you will just need a base template including your styles and scripts which serves a full HTML page (capable of serving ads). You can use this template to render your posts and load them into the main view. The loadNext(); function looks a little different this time, more like this.
 // Load the next part of the site into the main site in an iframe
function loadNext() {
    if (!loading && page > 1) {
        loading = true;
        page = page - 1;
        var scrollContainer = document.getElementById("scroll-container");
        const urlParams = new URLSearchParams(window.location.search);
        var lang = '';
        if (urlParams.get('lang') != null) {
            lang = "&lang=" + urlParams.get('lang');
        }
        const url = "uglek.com/scroll/page/?page=" + page + lang;
        var iframe = document.createElement('iframe');
        iframe.src = url;
        iframe.frameBorder = 0;
        iframe.scrolling = 'no';
        iframe.style.width = '100%';
        iframe.classList.add('mb-3');
        $(iframe).attr('target', '_parent');
        iframe.onload = function() { // Adjust size of iframe on load
            iframe.height = iframe.contentWindow.document.body.scrollHeight + 'px';
            loading = false;
        };
        scrollContainer.appendChild(iframe); // Append it to the document
    }
}
This is all it takes to create an infinitely scrolling Django website. You will be able to automatically load in new posts as you scroll using this code. I am making use of this on the homepage, where you can now scroll to older posts without pressing a button for the next page.


@Jasper_Holton's صورة الملف الشخصي

Database-Driven Translation Caching Django Template Filter This is a Django template filter designed to cache translations. It uses database models representing the translations and then queries them by text so you can render text in any language on a website, and only translate the text once. I have also included the code I use to translate the text, using NLP Translation from RapidAPI.com, as well as middleware to get the request in a template filter (in order to get the language). This code relies on the browser's language code, as well as a query string, ?lang=, to render the text in the users' languages. I have added comments to describe how the code works. The code begins with some middleware:

# app/middleware.py
from threading import local # Imports
from django.utils.deprecation import MiddlewareMixin

_request = local() # Store the request

class CurrentRequestMiddleware(MiddlewareMixin): # Use a middleware mixin to save the request
    def process_request(self, request):
        _request.value = request

def get_current_request(): # Return the request
    try:
        return _request.value
    except AttributeError:
        return None
Next is some settings
# project/settings.py
MIDDLEWARE = [
    'blog.middleware.CurrentRequestMiddleware', # The middleware we just made for the request
    'django.middleware.locale.LocaleMiddleware' # Middleware to store the language code in the request
]
And a model to store the translations.
# app/models.py
from django.db import models
class Translation(models.Model):
    id = models.AutoField(primary_key=True)
    src = models.CharField(max_length=2, default='en')
    lang = models.CharField(max_length=2, default='en')
    value = models.TextField(blank=True)
    translated = models.TextField(blank=True)
Lastly, the template filters and some helper functions to make them work
# app/templatetags/app_filters.py

from app.models import Translation # Imports
from app.middleware import get_current_request
from django import template

register = template.Library() # Register the template library

def get_lang(): # Get the language to translate to
    request = get_current_request()
    lang = request.LANGUAGE_CODE
    if(request.GET.get('lang', '') != ''):
        lang = request.GET.get('lang', '')
    if lang == None:
        lang = 'en'
    return lang

# Tranlsate a string to any language
def translateval(value, lang, src=None):
    src = src if src != None else 'en'
    if lang == src:
        return value
    trans = Translation.objects.filter(value=value,lang=lang,src=src if src != None else 'en') # Get the translation
    if trans.count() > 0: # Return it if it exists
        return trans.first().translated
    else: # Otherwise create it
        originalvalue = value
        value = value.replace('\n', '
') # Preserve newlines
        translation = ''
        try:
            translation = requests.request("GET", url, headers=headers, params={"text": value, "to": lang, "from": src if src != None else 'en', 'protected_words': '@;
;'}).json()['translated_text'][lang]'protected_words>
        except:
            translation = value
        translation = translation.replace('
', '\n').replace('
','\n').replace('
', '\n') # Newline fix, to preserve newlines
        ntrans = Translation.objects.create(value=originalvalue,lang=lang,src=src if src != None else 'en', translated=translation) # Create a new translation
        ntrans.save()
        return ntrans.translated # Return the translated value

# A template filter to translate from english to any language
@register.filter('etran') # Register the filter to translate
def etran(value):
    lang = get_lang() # Get the language
    translation = None
    if not lang == 'en':
        try:
            translation = translateval(value, lang, 'en') # Translate using NLP translation
        except:
            translation = None
    if translation != None:
        return translation
    return value
In action, this looks like
{{ 'Here is some text. This text will be translated from English to another language'|etran }}
I hope you find this Django code useful. I want to post lots of useful Python here so people can read it and make use of it in their own code. This code does a great job of translating all the text on the site to render it in the proper language.