Django แทนที่การบันทึกสำหรับรุ่น


134

ก่อนบันทึกโมเดลฉันปรับขนาดรูปภาพอีกครั้ง แต่ฉันจะตรวจสอบได้อย่างไรว่ามีการเพิ่มรูปภาพใหม่หรือเพียงแค่คำอธิบายที่อัปเดตดังนั้นฉันสามารถข้ามการลดขนาดได้ทุกครั้งที่บันทึกโมเดล

class Model(model.Model):
    image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()


    def save(self, *args, **kwargs):
        if self.image:
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

ฉันต้องการขายต่อเฉพาะเมื่อมีการโหลดรูปภาพใหม่หรือรูปภาพที่อัปเดต


คุณกำลังปรับขนาดเป็นขนาดคงที่ 100x100 หรือไม่
bdd

3
คุณอาจพบdjango-imagekitประโยชน์
vikingosegundo

คำตอบ:


135

ความคิดบางอย่าง:

class Model(model.Model):
    _image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()

    def set_image(self, val):
        self._image = val
        self._image_changed = True

        # Or put whole logic in here
        small = rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)

    def get_image(self):
        return self._image

    image = property(get_image, set_image)

    # this is not needed if small_image is created at set_image
    def save(self, *args, **kwargs):
        if getattr(self, '_image_changed', True):
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

ไม่แน่ใจว่ามันจะเล่นได้ดีกับเครื่องมือ django หลอกอัตโนมัติ (ตัวอย่าง: ModelForm, contrib.admin และอื่น ๆ )


1
ดูดี. แต่ฉันไม่สามารถเปลี่ยนชื่อภาพเป็น _image นั่นสำคัญหรือไม่?
Pol

ตกลงฉันแก้ไขด้วย db_column = 'image' แต่เหล็กไม่ทำงาน!
Pol

1
เป็นวิธีที่น่าสนใจมาก .. โดยฉันไม่เข้าใจอย่างเต็มที่ คุณช่วยอธิบายเพิ่มเติมให้ชัดเจนได้มั้ย หรือหว่านบทความบางอย่าง?
Pol

มันไม่ได้ผลสำหรับฉันเช่นกัน set_image ไม่เคยเรียก ดูเหมือนว่าสิ่งนี้ Django จะไม่ได้รับการสนับสนุนอย่างเป็นทางการ
Ivan Borshchov

16

ตรวจสอบฟิลด์ pk ของโมเดล ถ้าเป็น None แสดงว่าเป็นวัตถุใหม่

class Model(model.Model):
    image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()


    def save(self, *args, **kwargs):
        if 'form' in kwargs:
            form=kwargs['form']
        else:
            form=None

        if self.pk is None and form is not None and 'image' in form.changed_data:
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

แก้ไข: ฉันได้เพิ่มการตรวจสอบสำหรับ 'ภาพ' ใน form.changed_data นี่ถือว่าคุณใช้ไซต์ผู้ดูแลระบบเพื่ออัปเดตรูปภาพของคุณ คุณจะต้องแทนที่เมธอด save_model เริ่มต้นตามที่ระบุด้านล่าง

class ModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.save(form=form)

ฉันคิดว่าคุณพูดถูก ... สมมติว่าเขาใช้ไซต์ผู้ดูแลระบบเขาสามารถแทนที่ save_model ใน AdminModel ของเขาเพื่อส่งแบบฟอร์มไปยังบันทึกและตรวจสอบว่า 'รูปภาพ' อยู่ใน form.changed_data หรือไม่ ฉันจะอัปเดตทันทีที่ฉันมีเวลา
DM Graves

ใช้งานได้ก็ต่อเมื่อวัตถุนั้นใหม่ตามที่คุณพูด หากคุณอัปโหลดภาพใหม่การลดขนาดภาพจะไม่เปิดขึ้น
Jonathan

2
"self.pk คือ None" ไม่ทำงานหากมีการระบุ id ดังนั้น: Model.objects.get_or_create (id = 234, ... ) จะไม่ทำงานในโซลูชันนี้
nuts

6

คุณอาจระบุเหตุผลเพิ่มเติมเพื่อยืนยันว่ามีการโพสต์ภาพใหม่
สิ่งที่ต้องการ:

def save(self, new_image=False, *args, **kwargs):
    if new_image:
        small=rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)
    super(Model, self).save(*args, **kwargs)

หรือส่งคำขอตัวแปร

def save(self, request=False, *args, **kwargs):
    if request and request.FILES.get('image',False):
        small=rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)
    super(Model, self).save(*args, **kwargs)

ฉันคิดว่าสิ่งเหล่านี้จะไม่ทำลายบันทึกของคุณเมื่อเรียกง่ายๆ

คุณสามารถใส่สิ่งนี้ไว้ใน admin.py ของคุณเพื่อให้สามารถทำงานกับไซต์ผู้ดูแลระบบได้ (สำหรับวิธีแก้ปัญหาข้อที่สองจากด้านบน):

class ModelAdmin(admin.ModelAdmin):

    ....
    def save_model(self, request, obj, form, change): 
        instance = form.save(commit=False)
        instance.save(request=request)
        return instance

มันบอกฉันว่า: 'WSGIRequest' object ไม่มี attribute 'FILE'
Pol

sry FILES แทนที่จะเป็น FILE อัปเดตเป็น requestFILES.get ('image', False) แทนการร้องขอ FILES ['image'] สิ่งนี้จะหลีกเลี่ยงข้อยกเว้น
crodjer

3

สิ่งที่ฉันทำเพื่อให้บรรลุเป้าหมายคือทำสิ่งนี้ ..

# I added an extra_command argument that defaults to blank
def save(self, extra_command="", *args, **kwargs):

และด้านล่างวิธีการบันทึก () คือ ..

# override the save method to create an image thumbnail
if self.image and extra_command != "skip creating photo thumbnail":
    # your logic here

ดังนั้นเมื่อฉันแก้ไขบางฟิลด์ แต่ไม่แก้ไขภาพฉันใส่สิ่งนี้ ..

Model.save("skip creating photo thumbnail")

คุณสามารถแทนที่"skip creating photo thumbnail"ด้วย"im just editing the description"หรือเป็นข้อความที่เป็นทางการมากขึ้น

หวังว่าอันนี้จะช่วย!


2

ค้นหาฐานข้อมูลสำหรับระเบียนที่มีอยู่ด้วย PK เดียวกัน เปรียบเทียบขนาดไฟล์และเช็คซัมของรูปภาพใหม่และรูปภาพที่มีอยู่เพื่อดูว่าเป็นไฟล์เดียวกันหรือไม่


1

Django 3: การเอาชนะวิธีแบบจำลองที่กำหนดไว้ล่วงหน้า

from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def save(self, *args, **kwargs):
        do_something()
        super().save(*args, **kwargs)  # Call the "real" save() method.
        do_something_else()

สิ่งสำคัญคืออย่าลืมเรียกวิธีซูเปอร์คลาสนั่นคือsuper().save(*args, **kwargs)ธุรกิจนั้น เพื่อให้แน่ใจว่าวัตถุยังคงได้รับการบันทึกลงในฐานข้อมูล หากคุณลืมที่จะเรียกวิธีการ Superclass พฤติกรรมเริ่มต้นจะไม่เกิดขึ้นและฐานข้อมูลจะไม่ได้สัมผัส


0

ในเวอร์ชั่นใหม่มันเป็นแบบนี้:

def validate(self, attrs):
    has_unknown_fields = set(self.initial_data) - set(self.fields.keys())
    if has_unknown_fields:
        raise serializers.ValidationError("Do not send extra fields")
    return attrs

0

ฉันพบวิธีที่ง่ายอีกวิธีหนึ่งในการจัดเก็บข้อมูลลงในฐานข้อมูล

models.py

class LinkModel(models.Model):
    link = models.CharField(max_length=500)
    shortLink = models.CharField(max_length=30,unique=True)

ในฐานข้อมูลฉันมีเพียง 2 ตัวแปร

views.py

class HomeView(TemplateView):
    def post(self,request, *args, **kwargs):
        form = LinkForm(request.POST)

        if form.is_valid():
            text = form.cleaned_data['link'] # text for link

        dbobj = LinkModel()
        dbobj.link = text
        self.no = self.gen.generateShortLink() # no for shortLink
        dbobj.shortLink = str(self.no)
        dbobj.save()         # Saving from views.py

ในนี้ฉันได้สร้างอินสแตนซ์ของแบบจำลองใน views.py เท่านั้นและวาง / บันทึกข้อมูลลงใน 2 ตัวแปรจากมุมมองเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.