Как исправить IntegrityError в процессе сохранения обрезанных фотографий - PullRequest
0 голосов
/ 25 марта 2020

Имея модель:

class Photo(models.Model):
    file = models.ImageField(upload_to='cropped_photos/',null=True,blank=True)
    description = models.CharField(max_length=255, blank=True)
    uploaded_at = models.DateTimeField(auto_now_add=True)
    customer = models.ForeignKey(Woo_Customer,verbose_name="Customer",on_delete = models.CASCADE)

Я испытываю трудности в процессе сохранения фотографии для указанного клиента c после процедуры загрузки и обрезки изображения с помощью плагина обрезки.

Я не знаю, как передать идентификатор моего FK (клиента) в запись фотографии на этапе создания записи фотографии.

Вот моя форма:

class PhotoForm(ModelForm):
    x = FloatField(widget=HiddenInput())
    y = FloatField(widget=HiddenInput())
    width = FloatField(widget=HiddenInput())
    height = FloatField(widget=HiddenInput())

    class Meta:
        model = Photo
        fields = ('file', 'x', 'y', 'width', 'height')

    def save(self):
        photo = super(PhotoForm, self).save()

        x = self.cleaned_data.get('x')
        y = self.cleaned_data.get('y')
        w = self.cleaned_data.get('width')
        h = self.cleaned_data.get('height')

        image = Image.open(photo.file)
        cropped_image = image.crop((x, y, w+x, h+y))
        resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS)
        resized_image.save(photo.file.path)

        return photo

Вот мой взгляд:

def customer_photo_gallery(request,pk):
    photos = Photo.objects.filter(customer_id = pk)
    customer = Woo_Customer.objects.get(id = pk)
    if request.method == 'POST':
        form = PhotoForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('photo_list')
    else:
        form = PhotoForm()
    return render(request, 'woo_customer/woo_customer_photo_gallery.html', {'form': form, 'photos': photos , 'customer': customer})

Вот шаблон с использованием плагина cropper (https://fengyuanchen.github.io/cropper/)

{% block content %}

  <script>
    $(function () {

      /* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
      $("#id_file").change(function () {
        if (this.files && this.files[0]) {
          var reader = new FileReader();
          reader.onload = function (e) {
            $("#image").attr("src", e.target.result);
            $("#modalCrop").modal("show");
          }
          reader.readAsDataURL(this.files[0]);
        }
      });

      /* SCRIPTS TO HANDLE THE CROPPER BOX */
      var $image = $("#image");
      var cropBoxData;
      var canvasData;
      $("#modalCrop").on("shown.bs.modal", function () {
        $image.cropper({
          viewMode: 1,
          aspectRatio: 1/1,
          minCropBoxWidth: 200,
          minCropBoxHeight: 200,
          ready: function () {
            $image.cropper("setCanvasData", canvasData);
            $image.cropper("setCropBoxData", cropBoxData);
          }
        });
      }).on("hidden.bs.modal", function () {
        cropBoxData = $image.cropper("getCropBoxData");
        canvasData = $image.cropper("getCanvasData");
        $image.cropper("destroy");
      });

      $(".js-zoom-in").click(function () {
        $image.cropper("zoom", 0.1);
      });

      $(".js-zoom-out").click(function () {
        $image.cropper("zoom", -0.1);
      });

      /* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
      $(".js-crop-and-upload").click(function () {
        var cropData = $image.cropper("getData");
        $("#id_x").val(cropData["x"]);
        $("#id_y").val(cropData["y"]);
        $("#id_height").val(cropData["height"]);
        $("#id_width").val(cropData["width"]);
        $("#formUpload").submit();
      });

    });
  </script>





  <h4 class="page-header">Photo Gallery Album of Customer : {{customer.first_name}} {{customer.last_name}}</h4>

  <!-- FORM TO UPLOAD THE IMAGES -->
  <form method="post" enctype="multipart/form-data" id="formUpload">
    {% csrf_token %}
    {{ form }}
  </form>

  <!-- MODAL TO CROP THE IMAGE -->
  <div class="modal fade" id="modalCrop">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title">Crop the photo</h4>
        </div>
        <div class="modal-body">
          <img src="" id="image" style="max-width: 100%;">
        </div>
        <div class="modal-footer">
          <div class="btn-group pull-left" role="group">
            <button type="button" class="btn btn-default js-zoom-in">
              <span class="glyphicon glyphicon-zoom-in"></span>
            </button>
            <button type="button" class="btn btn-default js-zoom-out">
              <span class="glyphicon glyphicon-zoom-out"></span>
            </button>
          </div>
          <button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
          <button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
        </div>
      </div>
    </div>
  </div>

  <!-- CONTAINER TO DISPLAY THE CROPPED IMAGES -->
  <div class="row" style="margin-top: 20px">
    {% for photo in photos %}
      <div class="col-sm-4 col-md-3">
        <img src="{{ photo.file.url }}" class="thumbnail">
      </div>
    {% endfor %}
  </div>

{% endblock %}

Как это возможно присвоить идентификатор записи фотографии, поскольку последняя создается с javascript в шаблоне, а не в представлении?

После нажатия кнопки Обрезать и загрузить я получил ошибку "(1048, "Column 'customer_id' cannot be null")

Вот трассировка:

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py" in execute
  71.             return self.cursor.execute(query, args)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/MySQLdb/cursors.py" in execute
  209.         res = self._query(query)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/MySQLdb/cursors.py" in _query
  315.         db.query(q)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/MySQLdb/connections.py" in query
  226.         _mysql.connection.query(self, query)

During handling of the above exception ((1048, "Column 'customer_id' cannot be null")), another exception occurred:

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/www/wwwroot/yachts_management/yachts_management/intranet/views.py" in customer_photo_gallery
  4191.             form.save()

File "/www/wwwroot/yachts_management/yachts_management/intranet/forms.py" in save
  271.         photo = super(PhotoForm, self).save()

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/forms/models.py" in save
  458.             self.instance.save()

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/base.py" in save
  741.                        force_update=force_update, update_fields=update_fields)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/base.py" in save_base
  779.                 force_update, using, update_fields,

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/base.py" in _save_table
  870.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/base.py" in _do_insert
  908.                                using=using, raw=raw)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/query.py" in _insert
  1186.         return query.get_compiler(using=using).execute_sql(return_id)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1335.                 cursor.execute(sql, params)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/utils.py" in execute
  99.             return super().execute(sql, params)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/utils.py" in execute
  67.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
  76.         return executor(sql, params, many, context)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/utils.py" in _execute
  84.                 return self.cursor.execute(sql, params)

File "/www/wwwroot/yachts_management/yachts_manage_venv/lib/python3.7/site-packages/django/db/backends/mysql/base.py" in execute
  76.                 raise utils.IntegrityError(*tuple(e.args))

Exception Type: IntegrityError at /private/customer/photo_gallery/532/
Exception Value: (1048, "Column 'customer_id' cannot be null")

1 Ответ

0 голосов
/ 26 марта 2020

вы должны передать pk, т.е. customer_id, настроив urls.py, и когда вы нажмете соответствующий URL, из браузера вам нужно будет передать идентификатор в качестве параметра, например,

localhost:8080/path_that_renders_ customer_photo_gallery?id=1

from django.url import path
from . import views

urlpatterns = [
   path('path_that_renders_customer_photo_gallery/<int:pk>/', views.customer_photo_gallery)
]

`

...