here is the form code:
from django import forms
from .models import Image
from django.core.files.base import ContentFile
from django.utils.text import slugify
import requests
class ImageCreateForm(forms.ModelForm):
class Meta:
model = Image
fields = ['title', 'url', 'description']
widgets = {
'url': forms.HiddenInput,
}
def clean_url(self):
url = self.cleaned_data['url']
valid_extensions = ['jpg', 'jpeg', 'png']
extension = url.rsplit('.', 1)[1].lower()
if extension not in valid_extensions:
raise forms.ValidationError('The given URL does not ' \
'match valid image extensions.')
return url
def save(self, force_insert=False,
force_update=False,
commit=True):
image = super().save(commit=False)
image_url = self.cleaned_data['url']
name = slugify(image.title)
extension = image_url.rsplit('.', 1)[1].lower()
image_name = f'{name}.{extension}'
# download image from the given URL
response = requests.get(image_url)
image.image.save(image_name,
ContentFile(response.content),
save=False)
if commit:
image.save()
return image
here is the views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.shortcuts import get_object_or_404
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.http import HttpResponse
from django.core.paginator import Paginator, EmptyPage, \
PageNotAnInteger
from .forms import ImageCreateForm
from .models import Image
@login_required
def image_create(request):
if request.method == 'POST':
# form is sent
form = ImageCreateForm(data=request.POST)
if form.is_valid():
# form data is valid
cd = form.cleaned_data
new_image = form.save(commit=False)
# assign current user to the item
new_image.user = request.user
new_image.save()
messages.success(request, 'Image added successfully')
# redirect to new created image detail view
return redirect(new_image.get_absolute_url())
else:
# build form with data provided by the bookmarklet via GET
form = ImageCreateForm(data=request.GET)
return render(request,
'images/image/create.html',
{'section': 'images',
'form': form})
def image_detail(request, id, slug):
image = get_object_or_404(Image, id=id, slug=slug)
return render(request,
'images/image/detail.html',
{'section': 'images',
'image': image})
@login_required
@require_POST
def image_like(request):
image_id = request.POST.get('id')
action = request.POST.get('action')
if image_id and action:
try:
image = Image.objects.get(id=image_id)
if action == 'like':
image.users_like.add(request.user)
else:
image.users_like.remove(request.user)
return JsonResponse({'status': 'ok'})
except Image.DoesNotExist:
pass
return JsonResponse({'status': 'error'})
@login_required
def image_list(request):
images = Image.objects.all()
paginator = Paginator(images, 8)
page = request.GET.get('page')
images_only = request.GET.get('images_only')
try:
images = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
images = paginator.page(1)
except EmptyPage:
if images_only:
# If AJAX request and page out of range
# return an empty page
return HttpResponse('')
# If page out of range return last page of results
images = paginator.page(paginator.num_pages)
if images_only:
return render(request,
'images/image/list_images.html',
{'section': 'images',
'images': images})
return render(request,
'images/image/list.html',
{'section': 'images',
'images': images})
here is the models code:
from django.db import models
from django.utils.text import slugify
from django.conf import settings
class Image(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,related_name='images_created',on_delete=models.CASCADE)
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200,blank=True)
url = models.URLField(max_length=2000)
image = models.ImageField(upload_to='images/%Y/%m/%d/')
description = models.TextField(blank=True)
created = models.DateField(auto_now_add=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='images_liked',blank=True)
class Meta:
indexes = [
models.Index(fields=['-created']),
]
ordering = ['-created']
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
HTML code:
{% extends "base.html" %}
{% block title %}Bookmark an image{% endblock %}
{% block content %}
<h1>Bookmark an image</h1>
<img src="{{ request.GET.url }}" class="image-preview">
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Bookmark it!">
</form>
{% endblock %}
just in case I program on my phone (Acode). I run the code on Termux