2013-02-25 5 views
0


Я определил простую модель в Django:Джанго - проверка модели формата поля

class Student(models.Model): 
    s_name = models.CharField(max_length=32) 
    s_gpa = models.FloatField(min=0.0, max=5.0, default=5.0) 
    s_year = models.IntegerField(min=1, max=10, default=1) 
    s_registered = models.DateTimeField(auto_now_add=True) 

    def __unicode__(self): 
     return self.username 

    def modify(self, **kwargs): 
     if valid(self, kwargs): 
      for k,v in kwargs.iteritems(): 
       setattr(self, k, v) 
      self.save() 

def valid(s, kwargs): 
    # For all k,v pairs in kwargs 
    # (1) Checks if k is one of the attributes of s. Returns False if fails. 
    # (2) Checks if v fits the format defined for attribute k of s. 
    # Returns False if fails. 
    # Returns True if reaches this point. 

Я пишу функцию в силе, которую я хотел бы выполнить команды, описанные в комментариях.
Для (1), я использую

if k not in s.__dict__: return False 

я должен был бы некоторую помощь с (2).
То есть, Как я могу проверить, соответствует ли значение формату, определенному для атрибута (поле модели Django)?

Например: valid (s_name = True) и valid (s_name = 33 * 'a') должны возвращать False.

Примечание: Я пытаюсь решить эту проверку без использования форм.

+0

Как и в стороне - это обычная практика, чтобы использовать «я» в качестве первого аргумента к вашему методу - http://www.python.org/dev/peps/pep-0008/#function-and-method-arguments –

+0

Спасибо, Айдан за это.На самом деле, мое намерение состоит в том, чтобы иметь действительный() независимый от Студента. Я импортирую его из отдельного модуля utils. Это был несчастный случай, когда я оставил его в определении Студента. Еще раз спасибо за то, что привлек мое внимание. – 2013-02-25 18:08:31

+0

Я все еще не уверен, что это путь. Посмотрите мой обновленный ответ и, возможно, еще раз взгляните на документы проверки модели. –

ответ

1

Обе ваши valid и modify функции, вероятно, следует заменить метод clean.

Посмотрите в документации на model validation

UPDATE 1

Вы могли бы упасть действительный метод вообще и просто позвонить self.clean_feilds() вместо этого. Это будет проверять поля -

def modify(self, **kwargs): 
    try: 
     self.clean_fields() 
     for k,v in kwargs.iteritems(): 
      setattr(self, k, v) 
     self.save() 
    except: 
     pass 

UPDATE 2

Это звучит из ваших комментариев, что вам не нужно, чтобы вызвать любую проверку самостоятельно на всех. Просто позвоните save, а затем поймайте ValidationError, если ваши изменения недействительны.

def modify(self, **kwargs): 
    try: 
     for k,v in kwargs.iteritems(): 
      setattr(self, k, v) 
     self.save() 
    except ValidationError: 
     #... do something? 

Следует отметить, что многие программисты на языке питона предпочитают шаблон try/except, если он действителен/тогда. Он известен как принцип «лучше просить прощения, чем разрешение» (среди прочего он обеспечивает защиту от условий гонки - вероятно, не имеет значения в этом случае)

+0

Хороший ответ. Это выглядит наиболее кратким. Выше я пытался предоставить возможность протестировать отдельное поле, которое не похоже на функцию, на которую действительно задан вопрос. – Cole

+0

Думаю, я понимаю, о чем вы говорите. Поэтому, когда мы вызываем self.clean_fields(), он принимает экземпляр Student (self), проверяет его поля и вызывает какое-то исключение, если что-то не проверяет. В вашем примере, однако, не следует ли мы сначала вызвать цикл на kwargs с помощью setattr, а затем вызвать clean_fields при новом образе этого парня? И только call self.save(), если очистка не вызывает исключения. – 2013-02-25 19:19:43

+0

Я подумал (из вашего кода), что вы хотите проверить поля, а затем установить свои атрибуты. Если вам нужно, то, возможно, вы можете снова подтвердить его с помощью self.full_clean после добавления атрибутов (но до сохранения). –

0

Используйте s или self по необходимости.

def valid(self, kwargs): 
    for k, v in kwargs: 
     old_v = self.__dict__[k] 
     self.__dict__[k] = v 
     try: 
      self.save() 
      self.__dict__[k] = old_v 
      self.save() 
     except: 
      return False 

     return True 

Существует вероятность более прямой путь, чтобы выполнить тест, чем фактическое «self.save()» провал, но хорошее место, чтобы начать.

В качестве альтернативы:

field_list = ['s_name', 's_gpa', 's_year', 's_registered'] 
def valid(self, kwargs): 
    for k, v in kwargs: 
     exclude_list = [f for f in field_list if f != k] 
     try: 
      self.clean_fields(exclude=exclude_list) 
     except ValidationError: 
      return False 

     return True 

С списком пониманием, устранить exclude_list линии и изменить self.clean_fields линию:

self.clean_fields(exclude=[f for f in field_list if f != k]) 
Смежные вопросы