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
U को django-imagekit उपयोगी हो सकता है
vikoseosegundo

जवाबों:


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
अच्छा लगता है। लेकिन मैं छवि का नाम नहीं बदल सकता। क्या यह महत्वपूर्ण है?
पोल

ठीक है मैंने इसे db_column = 'image' के साथ हल किया। लेकिन यह इस्पात काम नहीं करता है!
पोल

1
यह बहुत दिलचस्प तरीका है .. मैं इसे पूरी तरह से नहीं समझता। क्या आप कृपया इसे और अधिक स्पष्ट रूप से समझा सकते हैं? या कुछ लेख बोओ?
पोल

यह मेरे लिए भी काम नहीं है,। set_image कभी नहीं कहा जाता है। इस तरह दिखता है कि कुछ Django आधिकारिक तौर पर समर्थित सामान नहीं है
इवान बोरशचोव

16

मॉडल के पीके क्षेत्र की जांच करें। यदि यह कोई नहीं है, तो यह एक नई वस्तु है।

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 में ओवरराइड कर सकता है ताकि फ़ॉर्म को सहेजने के माध्यम से पास किया जा सके, और जांचें कि क्या 'image' form.changed_data में है। समय मिलते ही मैं अपडेट करूंगा।
DM कब्रों

यह केवल तभी काम करता है जब ऑब्जेक्ट आपके अनुसार नया हो। यदि आप एक नई तस्वीर अपलोड करते हैं तो रीकॉलिंग ट्रिगर नहीं होगी।
जोनाथन

2
"self.pk कोई नहीं है" काम नहीं करता है अगर कोई आईडी निर्दिष्ट करता है, तो: Model.objects.get_or_create (id = 234, ...) इस समाधान में काम नहीं करेगा
नट

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' ऑब्जेक्ट की कोई विशेषता 'FILE' नहीं है
Pol

sry फ़ाइल के बजाय अपनी फ़ाइलें, request.FILES.get ( 'छवि', झूठी) के बजाय request.FILES [ 'छवि'] के लिए अद्यतन, इस अपवाद से बचने जाएगा
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

उसी पीके के साथ मौजूदा रिकॉर्ड के लिए डेटाबेस को क्वेरी करें। यह देखने के लिए कि क्या वे समान हैं, नई और मौजूदा छवियों के फ़ाइल आकार और चेकसम की तुलना करें।


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)व्यवसाय है - यह सुनिश्चित करने के लिए कि ऑब्जेक्ट अभी भी डेटाबेस में सहेजा गया है। यदि आप सुपरक्लास पद्धति को कॉल करना भूल जाते हैं, तो डिफ़ॉल्ट व्यवहार नहीं होगा और डेटाबेस को छुआ नहीं जाएगा।


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

इसमें मैंने केवल विचार में मॉडल का उदाहरण बनाया है और केवल विचारों से 2 चर में डेटा की बचत / बचत की है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.