Перепишите Django ImageField для приема абсолютных URI, а также файлов

Что ImageField делает под капотом, так это сохраняет путь к изображению в виде строки в базе данных. Я хотел бы переписать поле таким образом, чтобы оно могло принимать либо двоичный файл изображения, либо абсолютный путь URI и возвращать путь в виде строки и хранить его как char в базе данных.

Какой метод должен быть перезаписан для выполнения этой операции?

Спасибо

Чтобы выполнить эту операцию, вам, вероятно, придется переопределить метод save() поля ImageField, чтобы обрабатывать как двоичные файлы изображений, так и абсолютные пути URI.

Вот пример того, как это можно сделать:

class MyImageField(models.ImageField):
    def save(self, name, content, save=True):
        if isinstance(content, str):
            if content.startswith('http'):
                # it is an URI, let's download the file
                response = requests.get(content)
                content = ContentFile(response.content)
                name = os.path.join(settings.MEDIA_ROOT, name)
            else:
                # it is a binary image file
                content = ContentFile(content)
        super().save(name, content, save)

Это пользовательское поле проверяет, является ли переданное содержимое строкой, если да, то проверяет, начинается ли она с "http" (указывая, что это URI) или нет. Если это URI, он загрузит файл с помощью библиотеки requests и создаст объект ContentFile, который ожидает Django ImageField, с содержимым загруженного изображения. Если это не URI, то будет создан объект ContentFile с переданным бинарным изображением.

Вам следует использовать это пользовательское поле в вашей модели вместо оригинального ImageField.

class MyModel(models.Model):
    my_image = MyImageField(upload_to='my_images')

Возможно, вам потребуется дополнительная модификация в зависимости от вашего случая использования.

Не забудьте отметить это как решение, если это помогло вам ^_^ .

Без переопределения ImageField() вы можете сделать эти вещи, используя один дополнительный URLField() вот так...

models.py

class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    image = models.ImageField(upload_to ='Products')
    img_abs_url = models.URLField(blank=True,null=True)

    def __str__(self):
        return self.name

form.py

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = "__all__" 
        exclude = ['img_abs_url']

views.py

def HomeView(request):
  form = ProductForm()
  products = Product.objects.all()
  if request.method == 'POST':
    form = ProductForm(request.POST,request.FILES)
    if form.is_valid():
      product_name = form.cleaned_data['name']
      image = form.cleaned_data['image']
      create_product = Product.objects.create(name=product_name,image=image)
      create_product.img_abs_url = request.build_absolute_uri(create_product.image.url)
      create_product.save()
  context = {'form': form, 'products': products}
  return render(request, 'index.html', context)

Выход (панель администратора)

enter image description here

Вернуться на верх