2011-02-18 17 views
14

से ट्रिम व्हाइटसाइट्स Django में charField के अंत से मैं सफेद जगहों (ट्रिम) कैसे पट्टी करूं?(डीजेगो) चार फील्ड

यहां मेरा मॉडल है, जैसा कि आप देख सकते हैं कि मैंने साफ तरीकों को डालने का प्रयास किया है लेकिन ये कभी नहीं चलते हैं।

मैंने name.strip(), models.charField().strip() करने का भी प्रयास किया है लेकिन ये या तो काम नहीं करते हैं।

क्या Charfield को मेरे लिए स्वचालित रूप से ट्रिम करने के लिए मजबूर करने का कोई तरीका है?

धन्यवाद।

from django.db import models 
from django.forms import ModelForm 
from django.core.exceptions import ValidationError 
import datetime 

class Employee(models.Model): 
    """(Workers, Staff, etc)""" 
    name    = models.CharField(blank=True, null=True, max_length=100) 

    def save(self, *args, **kwargs): 
     try: 
      # This line doesn't do anything?? 
      #self.full_clean() 
      Employee.clean(self) 
     except ValidationError, e: 
      print e.message_dict 

     super(Employee, self).save(*args, **kwargs) # Real save 

    # If I uncomment this, I get an TypeError: unsubscriptable object 
    #def clean(self): 
    # return self.clean['name'].strip() 

    def __unicode__(self): 
     return self.name 

    class Meta: 
     verbose_name_plural = 'Employees' 

    class Admin:pass 


class EmployeeForm(ModelForm): 
    class Meta: 
     model = Employee 

    # I have no idea if this method is being called or not 
    def full_clean(self):  
     return super(Employee), self.clean().strip() 
     #return self.clean['name'].strip() 

संपादित: मेरे नवीनतम संस्करण में अद्यतन कोड। मुझे यकीन नहीं है कि मैं क्या गलत कर रहा हूं क्योंकि यह अभी भी नाम फ़ील्ड को व्हाइटस्पेस (ट्रिमिंग) नहीं कर रहा है।

उत्तर

10

मॉडल सफाई को कॉल करना है (यह स्वचालित नहीं है) तो अपनी बचत विधि में कुछ self.full_clean() रखें।
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.full_clean

आपके फॉर्म के लिए, आपको छीनने वाले साफ डेटा को वापस करने की आवश्यकता है।

return self.cleaned_data['name'].strip() 

किसी तरह मुझे लगता है कि तुम सिर्फ सामान वह काम नहीं करता का एक समूह करने की कोशिश की। याद रखें कि रूप और मॉडल 2 बहुत ही अलग चीजें हैं। कैसे रूपों http://docs.djangoproject.com/en/dev/ref/forms/validation/

super(Employee), self.clean().strip() makes no sense at all!

मान्य करने के लिए पर रूपों डॉक्स पर

चेक अप अपने कोड तय है:

class Employee(models.Model): 
    """(Workers, Staff, etc)""" 
    name = models.CharField(blank=True, null=True, max_length=100) 

    def save(self, *args, **kwargs): 
     self.full_clean() # performs regular validation then clean() 
     super(Employee, self).save(*args, **kwargs) 


    def clean(self): 
     """ 
     Custom validation (read docs) 
     PS: why do you have null=True on charfield? 
     we could avoid the check for name 
     """ 
     if self.name: 
      self.name = self.name.strip() 


class EmployeeForm(ModelForm): 
    class Meta: 
     model = Employee 


    def clean_name(self): 
     """ 
     If somebody enters into this form ' hello ', 
     the extra whitespace will be stripped. 
     """ 
     return self.cleaned_data.get('name', '').strip() 
+0

मुझे अभी भी समस्याएं हैं - यह अभी भी व्हाइटस्पेस (ट्रिम) को अलग नहीं कर रहा है। मैंने आपके द्वारा पोस्ट किए गए ट्यूटोरियल और सहेजने के तरीके में full_clean() को कॉल करने का आपका विचार करने का प्रयास किया। मैं समझने के लिए संघर्ष कर रहा हूं) क्या कर्मचारी फॉर्म को बुलाया जा रहा है? बी) क्या full_clean() विधि कहा जा रहा है? मैंने अपने प्रश्न में अपना कोड नमूना अपडेट किया है। मुझे उम्मीद है कि मैं सही दिशा में इंगित कर सकता हूं। – zardon

+0

मुझे अपना कोड कॉपी और पेस्ट करने दें और इसे संशोधित करें। –

+0

आपकी मदद के लिए धन्यवाद, मैं Django/पायथन के लिए काफी नया हूँ; विभिन्न गलतियों और गलतफहमी के लिए माफी मांगती हूं कि मुझे विभिन्न सुविधाओं को कैसे कार्यान्वित किया जाना चाहिए। – zardon

3

मैं एक डेकोरेटर के रूप में विचारों में इस से निपटने कर रहा हूँ। मैं फील्ड वैल्यू को भी छोटा कर रहा हूं जो चारफिल्ल्ड max_length मान से अधिक है।

from django import forms 
from django import models 
from django.db.models.fields import FieldDoesNotExist 
from django.utils.encoding import smart_str 

class CleanCharField(forms.CharField): 
     """Django's default form handling drives me nuts wrt trailing 
     spaces. http://code.djangoproject.com/attachment/ticket/6362 
     """ 
     def clean(self, value): 
      if value is None: 
       value = u'' 
      value = smart_str(value).strip() 
      value = super(forms.CharField, self).clean(value) 
      return value 

def truncate_charfield(model): 
    """decorator to truncate CharField data to model field max_length. 
    Apply to the clean method in views Form: 

    @truncate_charfield(MyModel) 
    def clean(self): 
     ... 
    """ 
    def wrap(f): 
     def wrapped_f(*args): 
      f(*args) 
      d = args[0].cleaned_data 
      for field in model._meta.fields: 
       try: 
        mf = model._meta.get_field(field.name) 
        if isinstance(mf, models.CharField) and field.name in d: 
         d[field.name] = d[field.name][:mf.max_length] 
       except FieldDoesNotExist: 
        pass 
      return d 
     return wrapped_f 
    return wrap 
+0

जैसे किसी भी पायथन स्ट्रिंग ऑपरेशंस को सुरक्षित कर सकें, लेकिन धन्यवाद, लेकिन मेरे लिए थोड़ा बहुत उन्नत लगता है - मुझे यकीन नहीं है कि मैं यह फाइल कहां रखूंगा, मैं इसे कैसे कहूंगा, आदि; लेकिन जैसा कि मैं Django/पायथन उठाता हूं मुझे यकीन है कि मैं इसे सब कुछ रास्ते में उठाऊंगा। एक बार फिर धन्यवाद। – zardon

+0

ज़र्डन, आप बस इसे मॉड्यूल में डाल सकते हैं, maxtruncate.py फिर अपने विचारों में आयात करें: maxtruncate आयात से CleanCharField, truncate_charfield। फिर क्लीनफैरफ़ील्ड के साथ चारफिल्ड को प्रतिस्थापित करें और अपनी साफ विधि के शीर्ष पर truncate_charfield सजावट रखें। मुख्य लाभ यह है कि आपके इनपुट क्षेत्र में आपके max_length से अधिक नहीं होगा ... जो आपके डेटाबेस से एक खराब रनटाइम त्रुटि उत्पन्न करेगा। –

19

जब आप मॉडल बनाने/संपादित करने के लिए मॉडलफॉर्म उदाहरण का उपयोग कर रहे हैं, तो मॉडल की साफ() विधि को कॉल करने की गारंटी है।

class Employee(models.Model): 
    """(Workers, Staff, etc)""" 
    name = models.CharField(blank=True, null=True, max_length=100) 

    def clean(self): 
     if self.name: 
      self.name = self.name.strip() 

मैं निम्नलिखित कोड स्निपेट प्राप्त useful- यह ट्रिम: तो, अगर आप एक क्षेत्र से खाली स्थान के पट्टी करना चाहते हैं, तो आप सिर्फ एक साफ() विधि अपने मॉडल (ModelForm वर्ग को संपादित करने की कोई जरूरत नहीं है) करने के लिए जोड़ मॉडल के क्षेत्रों जो अलग-अलग क्षेत्रों को निर्दिष्ट करने की जरूरत के बिना या तो CharField या TextField (तो यह भी URLField क्षेत्रों पकड़ता) उपवर्ग के सभी के लिए खाली स्थान के:

def clean(self): 
    for field in self._meta.fields: 
     if isinstance(field, (models.CharField, models.TextField)): 
      value = getattr(self, field.name) 
      if value: 
       setattr(self, field.name, value.strip()) 

किसी ने सही ढंग से आप उपयोग नहीं किया जाना चाहिए ने कहा अशक्त = सच नाम घोषणापत्र में।

def clean(self): 
    for field in self._meta.fields: 
     if isinstance(field, (models.CharField, models.TextField)): 
      setattr(self, field.name, getattr(self, field.name).strip()) 
+1

अच्छा समाधान। हालांकि, एक चीज जो मैं बदलूंगा वह है: ** यदि मान और हैशर (मान, 'स्ट्रिप'): ** कुछ कस्टम फ़ील्ड में किसी मान के लिए स्ट्रिप विधि नहीं है (कम से कम मेरा मामला है)। यह इसके खिलाफ सुरक्षा करता है। –

5

आप इतने सारे डेटा क्षेत्रों छांट करने का है, तो क्यों CharField विस्तार की कोशिश मत: सर्वश्रेष्ठ अभ्यास जो मामले से ऊपर सरल करने के लिए, अशक्त = स्ट्रिंग क्षेत्रों के लिए यह सच है से बचने के लिए है?

from django.db import models 
from django.utils.translation import ugettext_lazy as _ 

class TrimCharField(models.CharField): 
    description = _(
     "CharField that ignores leading" 
     " and trailing spaces in data") 

    def get_prep_value(self, value) 
     return trim(super(TrimCharField, self 
      ).get_prep_value(value)) 

    def pre_save(self, model_instance, add): 
     return trim(super(TrimCharField, self 
      ).pre_save(model_instance, add)) 

अद्यतन: Django संस्करणों < = 1 के लिए।7 यदि आप फ़ील्ड का विस्तार करना चाहते हैं, तो आप मॉडलों का उपयोग करना होगा। सबफील्डबेस मेटाक्लास। तो यहां यह होगा:

class TrimCharField(six.with_metaclass(
    models.SubfieldBase, models.CharField)): 
3

Django 1.9 इसे पूरा करने का एक आसान तरीका प्रदान करता है। strip तर्क का उपयोग करके जिसका डिफ़ॉल्ट सत्य है, आप यह सुनिश्चित कर सकते हैं कि अग्रणी और पिछला सफेद स्थान छंटनी हो। आप केवल फॉर्म फ़ील्ड्स में ऐसा कर सकते हैं ताकि यह सुनिश्चित किया जा सके कि उपयोगकर्ता इनपुट छंटनी हो। लेकिन वह अभी भी मॉडल की रक्षा नहीं करेगा। यदि आप अभी भी ऐसा करना चाहते हैं, तो आप ऊपर दिए गए किसी भी तरीके का उपयोग कर सकते हैं।

अधिक जानकारी के लिए देखें https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield

0

आप अभी भी Django पर नहीं हैं, तो आप (और मुझे) पर 1.9+ शर्म की बात है और अपने प्रपत्र में इस ड्रॉप। यह @ जेरेमी-लेविस के जवाब के समान है लेकिन मुझे उनके साथ कई समस्याएं थीं।

def clean_text_fields(self): 
    # TODO: Django 1.9, use on the model strip=True 
    # https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield 
    from django.forms.fields import CharField 
    cd = self.cleaned_data 
    for field_name, field in self.fields.items(): 
     if isinstance(field, CharField): 
      cd[field_name] = cd[field_name].strip() 
      if self.fields[field_name].required and not cd[field_name]: 
       self.add_error(field_name, "This is a required field.") 

def clean(self): 
    self.clean_text_fields() 
संबंधित मुद्दे