Javascript reoder model element saving db

Sorry , re-post code… error github delete casual.
My code.
models.py:

from django.db import models
from stdimage import StdImageField
from django.urls import reverse
from django.utils.translation import gettext as _
import os
from . utils import path_and_rename, resize_and_autorotate
from django.conf import settings
from datetime import *


class Album(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('Author') )
    title = models.CharField(max_length=255, verbose_name=_('Title'))
    content = models.TextField(verbose_name=_('Content'))
    slug = models.SlugField(null=False, unique=True, max_length=255, verbose_name=_('Slug'))
    status = models.BooleanField(default=0, verbose_name=_('Status'))
    created = models.DateTimeField(auto_now_add=True, verbose_name=_('Created'))
    updated = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))


    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('album', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

    class Meta:
        ordering = ['id']


class Photo(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('Author'))
    content = models.CharField(max_length=255, verbose_name=_('Content'))
    album = models.ForeignKey(Album, on_delete=models.CASCADE, related_name='ALBUM')
    photo = StdImageField(upload_to=path_and_rename, blank=True, render_variations= resize_and_autorotate, variations={
        'large': (640, 480),
        'thumbnail': (320, 220, True),
    }, delete_orphans=True, verbose_name=_('Photo'))
    order = models.IntegerField(default=0)    
    status = models.BooleanField(default=0, verbose_name=_('Status'))    
    created = models.DateTimeField(auto_now_add=True, verbose_name=_('Created'))  
    updated = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))

    def delete(self, *args, **kwargs):
        os.remove(os.path.join(settings.MEDIA_ROOT, self.photo.name))
        super().delete(*args, **kwargs)

    def save(self, *args, **kwargs):
        super(Photo, self).save(*args, **kwargs)
    
    def __str__(self):
        return f'{self.id}'
    class Meta:
        ordering = ("order",)


Views.py

class VediAlbum_sortable(DetailView):
    model = Photo
    context_object_name = 'photo'
    queryset = Photo.objects.filter(status=True)
    def get(self, request, album_slug):
        orgs = Album.objects.filter(slug__iexact = album_slug)
        if not orgs:
            return render(request, 'photo_404.html')
        else:
            photo = Photo.objects.filter(album__slug=album_slug, status=1)
            album = Album.objects.filter(slug__isnull = False, slug=album_slug).order_by('created')
        return render(request, 'photo_sortable.html', {'photo': photo, 'album': album})

urls.py

from django.urls import path
from . views import *
urlpatterns = [
    path('', ListaAlbum.as_view(), name='album'),
    path('<slug:album_slug>/', VediAlbum.as_view(), name='VediAlbum'),
    path('sortable_album/<slug:album_slug>/', VediAlbum_sortable.as_view(), name='VediAlbumSort'),
]

photo_sortable.html:

{% extends "master_admin.html" %}
{% load static %}
{% block title %} Edit :  {% for albumData in album %} {{albumData.title}} {%endfor%} {% endblock %}
<div class="row">
{% block _content %}
<div id="photo">
  <div class="row" id="sortable">
  {% for photoData in photo %}
  <div class="col-md-4 mb-3">
    <div class="card photo_card">
      <div class="card-header">
      </div>
      <div class="card-body photo_gallery">
        <p class="text-center"><a href="{% get_media_prefix %}{{photoData.photo.large }}"  class="big" ><img src="{% get_media_prefix %}{{photoData.photo.thumbnail }}" class="figure-img img-fluid rounded big" alt="{{photoData.content}}" title="{{photoData.content}}"></a></p>
      </div>
      <div class="card-footer">
      {{photoData.content}}
      
      </div>
    </div>
</div>
  {% endfor %}
</div>
  </div>
{% endblock %}


{% block _footer %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
  $(document).ready(function() {
    $("#sortable").sortable({
      update: function(event, ui) {
        var serial = $('#sortable').sortable('serialize');
    $.ajax({
      url: "",                     // ?? How to insert url ??
      type: "post",
      data: serial
    });
      },
    }).disableSelection();
  });
</script>
{% endblock %}

Idea insert url:

    $.ajax({
      url: "",                     // ?? How to insert url ??
      type: "post",
      data: serial
    });

How to saving order position in db.?

My error log:

[Sun Aug 07 20:48:08.204887 2022] [wsgi:error] [pid 26874] [remote ::1:36024] Forbidden (CSRF token missing or incorrect.): /photo/sortable_album/i-fiori-del-mio-giardino/

Browser console:

Failed to load resource: the server responded with a status of 403 (Forbidden)

Idea ? Solved problem ?

Thanks.

Hi , how to use method post in single DetailView.

class VediAlbum_sortable(DetailView):
    model = Photo
    context_object_name = 'photo'
    queryset = Photo.objects.filter(status=True)
    def post(self):
          pass           # How to possible implement ?
    def get(self, request, album_slug):
        orgs = Album.objects.filter(slug__iexact = album_slug)
        if not orgs:
            return render(request, 'photo_404.html')
        else:
            photo = Photo.objects.filter(album__slug=album_slug, status=1)
            album = Album.objects.filter(slug__isnull = False, slug=album_slug).order_by('created')
        return render(request, 'photo_sortable.html', {'photo': photo, 'album': album})

Thanks.

ok, how to get id field in saving order field ?

class VediAlbum_sortable(TemplateView):
    model = Photo
    context_object_name = 'photo'
    queryset = Photo.objects.filter(status=True)
    def get(self, request, album_slug):
        orgs = Album.objects.filter(slug__iexact = album_slug)
        if not orgs:
            return render(request, 'photo_404.html')
        else:
            photo = Photo.objects.filter(album__slug=album_slug, status=1)
            album = Album.objects.filter(slug__isnull = False, slug=album_slug).order_by('created')
        return render(request, 'photo_sortable.html', {'photo': photo, 'album': album})
    def post(self, request, album_slug):
        if request.method == 'POST':
            pass # how to get id on saving order field.
            HttpResponse('')
        return JsonResponse({'photo':'false'}) 

Check out the sortable API docs at Sortable Widget | jQuery UI API Documentation.

I think the serialize method would help you collect the data you need to submit to the view in your POST. The docs also give you some clues as to how you need to handle that submission in your view. (I’ve never used this directly, so I don’t have any specific example to share.)

Be aware that the way you have this coded, every time a person moves a photo to a new location, the entire list of photos is going to be sent to the server to be resequenced. Aside from the amount of work this is going to create on the server, there’s also the possibility that someone moving things around quickly could create their own race condition on the server such that the server ends up “out of sync” with the browser.

You may want to change your UI to provide a “save” button that sends the updated list to the server when it is pressed, and not on every change.

ok, implement button “save”.

thanks.

Hei, how to use timestamp model … update time micro second field created timestamp.
My modify update timestamp 00.00.01 … 00.00.02 00.00.03

ideas?
thanks

similar:

@csrf_exempt
def sort(request):
        reoder = Photo.objects.filter(id=request.POST.get("id")).update(photo_order=datetime.now)
        return reoder

not function working… correct function ??
error:

Forbidden (CSRF token missing or incorrect.): /photo/12/
[09/Aug/2022 17:48:38] "POST /photo/12/ HTTP/1.1" 403 2520

Idea how to problem fixed ???

This has nothing to do with your sort function. This error is being thrown before your function even begins to execute.

Read: Cross Site Request Forgery protection | Django documentation | Django.

ok, my code correct:

@csrf_exempt
def sort(request, id):
    orgs = Photo.objects.filter(id__iexact = id)
    if not orgs:
        return render(request, 'photo_404.html')
    else:
        try:
            Photo.objects.filter(id__iexact=id).update(photo_order=time.time_ns())
            print(time.time_ns())
        except ValueError:
            return render(request, 'photo_404.html')
    return HttpResponse('')

no update database … print(time.time_ns() ok … don’t update from db.

My debug:

1660296332594725800
[12/Aug/2022 11:25:32] "POST /photo/sort/12/ HTTP/1.1" 200 0

not change from db. How to fixed problem ?
thanks

I don’t see a field by that name in the model you posted in the original message of this thread. Is this correct?

sorry … my change name last minute: my code photo model :

class Photo(models.Model):

    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('Author'))
    content = models.CharField(max_length=255, verbose_name=_('Content'))
    album = models.ForeignKey(Album, on_delete=models.CASCADE, related_name='ALBUM')
    photo = StdImageField(upload_to=path_and_rename, blank=True, render_variations= resize_and_autorotate, variations={
        'large': (640, 480),
        'thumbnail': (320, 220, True),
    }, delete_orphans=True, verbose_name=_('Photo'))
    photo_order = models.PositiveBigIntegerField(verbose_name=_('photo order'))    
    status = models.BooleanField(default=0, verbose_name=_('Status'))    
    created = models.DateTimeField(auto_now_add=True, verbose_name=_('Created'))  
    updated = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))

    def delete(self, *args, **kwargs):
        os.remove(os.path.join(settings.MEDIA_ROOT, self.photo.name))
        super().delete(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.photo_order = time.time_ns()
        super(Photo, self).save(*args, **kwargs)
    
    def __str__(self):
        return f'{self.id}'
    class Meta:
        ordering = ("photo_order",)

views.py sort:

@csrf_exempt
def sort(request, id):
    try:
        Photo.objects.filter(id__iexact=id).update(photo_order=time.time_ns())
        print(time.time_ns())
    except ValueError:
        pass
    return HttpResponse('')

ok,
12 ID


12 ID

not working all photo

idea ? cilcle while all photo changed photo_order ? time_ns()?
Thanks.