1 import copy |
|
2 import types |
1 import types |
3 import sys |
2 import sys |
4 import os |
3 import os |
5 from itertools import izip |
4 from itertools import izip |
6 try: |
|
7 set |
|
8 except NameError: |
|
9 from sets import Set as set # Python 2.3 fallback. |
|
10 |
|
11 import django.db.models.manager # Imported to register signal handler. |
5 import django.db.models.manager # Imported to register signal handler. |
12 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError |
6 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS |
|
7 from django.core import validators |
13 from django.db.models.fields import AutoField, FieldDoesNotExist |
8 from django.db.models.fields import AutoField, FieldDoesNotExist |
14 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField |
9 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField |
15 from django.db.models.query import delete_objects, Q |
10 from django.db.models.query import delete_objects, Q |
16 from django.db.models.query_utils import CollectedObjects, DeferredAttribute |
11 from django.db.models.query_utils import CollectedObjects, DeferredAttribute |
17 from django.db.models.options import Options |
12 from django.db.models.options import Options |
18 from django.db import connection, transaction, DatabaseError |
13 from django.db import connections, router, transaction, DatabaseError, DEFAULT_DB_ALIAS |
19 from django.db.models import signals |
14 from django.db.models import signals |
20 from django.db.models.loading import register_models, get_model |
15 from django.db.models.loading import register_models, get_model |
21 from django.utils.functional import curry |
16 from django.utils.translation import ugettext_lazy as _ |
|
17 import django.utils.copycompat as copy |
|
18 from django.utils.functional import curry, update_wrapper |
22 from django.utils.encoding import smart_str, force_unicode, smart_unicode |
19 from django.utils.encoding import smart_str, force_unicode, smart_unicode |
|
20 from django.utils.text import get_text_list, capfirst |
23 from django.conf import settings |
21 from django.conf import settings |
24 |
|
25 |
22 |
26 class ModelBase(type): |
23 class ModelBase(type): |
27 """ |
24 """ |
28 Metaclass for all models. |
25 Metaclass for all models. |
29 """ |
26 """ |
393 field = self._meta.get_field_by_name(field_name)[0] |
419 field = self._meta.get_field_by_name(field_name)[0] |
394 except FieldDoesNotExist: |
420 except FieldDoesNotExist: |
395 return getattr(self, field_name) |
421 return getattr(self, field_name) |
396 return getattr(self, field.attname) |
422 return getattr(self, field.attname) |
397 |
423 |
398 def save(self, force_insert=False, force_update=False): |
424 def save(self, force_insert=False, force_update=False, using=None): |
399 """ |
425 """ |
400 Saves the current instance. Override this in a subclass if you want to |
426 Saves the current instance. Override this in a subclass if you want to |
401 control the saving process. |
427 control the saving process. |
402 |
428 |
403 The 'force_insert' and 'force_update' parameters can be used to insist |
429 The 'force_insert' and 'force_update' parameters can be used to insist |
404 that the "save" must be an SQL insert or update (or equivalent for |
430 that the "save" must be an SQL insert or update (or equivalent for |
405 non-SQL backends), respectively. Normally, they should not be set. |
431 non-SQL backends), respectively. Normally, they should not be set. |
406 """ |
432 """ |
407 if force_insert and force_update: |
433 if force_insert and force_update: |
408 raise ValueError("Cannot force both insert and updating in " |
434 raise ValueError("Cannot force both insert and updating in model saving.") |
409 "model saving.") |
435 self.save_base(using=using, force_insert=force_insert, force_update=force_update) |
410 self.save_base(force_insert=force_insert, force_update=force_update) |
|
411 |
436 |
412 save.alters_data = True |
437 save.alters_data = True |
413 |
438 |
414 def save_base(self, raw=False, cls=None, origin=None, |
439 def save_base(self, raw=False, cls=None, origin=None, force_insert=False, |
415 force_insert=False, force_update=False): |
440 force_update=False, using=None): |
416 """ |
441 """ |
417 Does the heavy-lifting involved in saving. Subclasses shouldn't need to |
442 Does the heavy-lifting involved in saving. Subclasses shouldn't need to |
418 override this method. It's separate from save() in order to hide the |
443 override this method. It's separate from save() in order to hide the |
419 need for overrides of save() to pass around internal-only parameters |
444 need for overrides of save() to pass around internal-only parameters |
420 ('raw', 'cls', and 'origin'). |
445 ('raw', 'cls', and 'origin'). |
421 """ |
446 """ |
|
447 using = using or router.db_for_write(self.__class__, instance=self) |
|
448 connection = connections[using] |
422 assert not (force_insert and force_update) |
449 assert not (force_insert and force_update) |
423 if cls is None: |
450 if cls is None: |
424 cls = self.__class__ |
451 cls = self.__class__ |
425 meta = cls._meta |
452 meta = cls._meta |
426 if not meta.proxy: |
453 if not meta.proxy: |
427 origin = cls |
454 origin = cls |
428 else: |
455 else: |
429 meta = cls._meta |
456 meta = cls._meta |
430 |
457 |
431 if origin: |
458 if origin and not meta.auto_created: |
432 signals.pre_save.send(sender=origin, instance=self, raw=raw) |
459 signals.pre_save.send(sender=origin, instance=self, raw=raw) |
433 |
460 |
434 # If we are in a raw save, save the object exactly as presented. |
461 # If we are in a raw save, save the object exactly as presented. |
435 # That means that we don't try to be smart about saving attributes |
462 # That means that we don't try to be smart about saving attributes |
436 # that might have come from the parent class - we just save the |
463 # that might have come from the parent class - we just save the |
465 record_exists = True |
492 record_exists = True |
466 manager = cls._base_manager |
493 manager = cls._base_manager |
467 if pk_set: |
494 if pk_set: |
468 # Determine whether a record with the primary key already exists. |
495 # Determine whether a record with the primary key already exists. |
469 if (force_update or (not force_insert and |
496 if (force_update or (not force_insert and |
470 manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by())): |
497 manager.using(using).filter(pk=pk_val).exists())): |
471 # It does already exist, so do an UPDATE. |
498 # It does already exist, so do an UPDATE. |
472 if force_update or non_pks: |
499 if force_update or non_pks: |
473 values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] |
500 values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] |
474 rows = manager.filter(pk=pk_val)._update(values) |
501 rows = manager.using(using).filter(pk=pk_val)._update(values) |
475 if force_update and not rows: |
502 if force_update and not rows: |
476 raise DatabaseError("Forced update did not affect any rows.") |
503 raise DatabaseError("Forced update did not affect any rows.") |
477 else: |
504 else: |
478 record_exists = False |
505 record_exists = False |
479 if not pk_set or not record_exists: |
506 if not pk_set or not record_exists: |
|
507 if meta.order_with_respect_to: |
|
508 # If this is a model with an order_with_respect_to |
|
509 # autopopulate the _order field |
|
510 field = meta.order_with_respect_to |
|
511 order_value = manager.using(using).filter(**{field.name: getattr(self, field.attname)}).count() |
|
512 setattr(self, '_order', order_value) |
|
513 |
480 if not pk_set: |
514 if not pk_set: |
481 if force_update: |
515 if force_update: |
482 raise ValueError("Cannot force an update in save() with no primary key.") |
516 raise ValueError("Cannot force an update in save() with no primary key.") |
483 values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] |
517 values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True), connection=connection)) |
|
518 for f in meta.local_fields if not isinstance(f, AutoField)] |
484 else: |
519 else: |
485 values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] |
520 values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True), connection=connection)) |
486 |
521 for f in meta.local_fields] |
487 if meta.order_with_respect_to: |
522 |
488 field = meta.order_with_respect_to |
|
489 values.append((meta.get_field_by_name('_order')[0], manager.filter(**{field.name: getattr(self, field.attname)}).count())) |
|
490 record_exists = False |
523 record_exists = False |
491 |
524 |
492 update_pk = bool(meta.has_auto_field and not pk_set) |
525 update_pk = bool(meta.has_auto_field and not pk_set) |
493 if values: |
526 if values: |
494 # Create a new record. |
527 # Create a new record. |
495 result = manager._insert(values, return_id=update_pk) |
528 result = manager._insert(values, return_id=update_pk, using=using) |
496 else: |
529 else: |
497 # Create a new record with defaults for everything. |
530 # Create a new record with defaults for everything. |
498 result = manager._insert([(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) |
531 result = manager._insert([(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True, using=using) |
499 |
532 |
500 if update_pk: |
533 if update_pk: |
501 setattr(self, meta.pk.attname, result) |
534 setattr(self, meta.pk.attname, result) |
502 transaction.commit_unless_managed() |
535 transaction.commit_unless_managed(using=using) |
503 |
536 |
504 if origin: |
537 # Store the database on which the object was saved |
|
538 self._state.db = using |
|
539 |
|
540 # Signal that the save is complete |
|
541 if origin and not meta.auto_created: |
505 signals.post_save.send(sender=origin, instance=self, |
542 signals.post_save.send(sender=origin, instance=self, |
506 created=(not record_exists), raw=raw) |
543 created=(not record_exists), raw=raw) |
507 |
544 |
508 save_base.alters_data = True |
545 save_base.alters_data = True |
509 |
546 |
515 When done, seen_objs.items() will be in the format: |
552 When done, seen_objs.items() will be in the format: |
516 [(model_class, {pk_val: obj, pk_val: obj, ...}), |
553 [(model_class, {pk_val: obj, pk_val: obj, ...}), |
517 (model_class, {pk_val: obj, pk_val: obj, ...}), ...] |
554 (model_class, {pk_val: obj, pk_val: obj, ...}), ...] |
518 """ |
555 """ |
519 pk_val = self._get_pk_val() |
556 pk_val = self._get_pk_val() |
520 if seen_objs.add(self.__class__, pk_val, self, parent, nullable): |
557 if seen_objs.add(self.__class__, pk_val, self, |
|
558 type(parent), parent, nullable): |
521 return |
559 return |
522 |
560 |
523 for related in self._meta.get_all_related_objects(): |
561 for related in self._meta.get_all_related_objects(): |
524 rel_opts_name = related.get_accessor_name() |
562 rel_opts_name = related.get_accessor_name() |
525 if isinstance(related.field.rel, OneToOneRel): |
563 if not related.field.rel.multiple: |
526 try: |
564 try: |
527 sub_obj = getattr(self, rel_opts_name) |
565 sub_obj = getattr(self, rel_opts_name) |
528 except ObjectDoesNotExist: |
566 except ObjectDoesNotExist: |
529 pass |
567 pass |
530 else: |
568 else: |
531 sub_obj._collect_sub_objects(seen_objs, self.__class__, related.field.null) |
569 sub_obj._collect_sub_objects(seen_objs, self, related.field.null) |
532 else: |
570 else: |
533 # To make sure we can access all elements, we can't use the |
571 # To make sure we can access all elements, we can't use the |
534 # normal manager on the related object. So we work directly |
572 # normal manager on the related object. So we work directly |
535 # with the descriptor object. |
573 # with the descriptor object. |
536 for cls in self.__class__.mro(): |
574 for cls in self.__class__.mro(): |
537 if rel_opts_name in cls.__dict__: |
575 if rel_opts_name in cls.__dict__: |
538 rel_descriptor = cls.__dict__[rel_opts_name] |
576 rel_descriptor = cls.__dict__[rel_opts_name] |
539 break |
577 break |
540 else: |
578 else: |
541 raise AssertionError("Should never get here.") |
579 # in the case of a hidden fkey just skip it, it'll get |
|
580 # processed as an m2m |
|
581 if not related.field.rel.is_hidden(): |
|
582 raise AssertionError("Should never get here.") |
|
583 else: |
|
584 continue |
542 delete_qs = rel_descriptor.delete_manager(self).all() |
585 delete_qs = rel_descriptor.delete_manager(self).all() |
543 for sub_obj in delete_qs: |
586 for sub_obj in delete_qs: |
544 sub_obj._collect_sub_objects(seen_objs, self.__class__, related.field.null) |
587 sub_obj._collect_sub_objects(seen_objs, self, related.field.null) |
|
588 |
|
589 for related in self._meta.get_all_related_many_to_many_objects(): |
|
590 if related.field.rel.through: |
|
591 opts = related.field.rel.through._meta |
|
592 reverse_field_name = related.field.m2m_reverse_field_name() |
|
593 nullable = opts.get_field(reverse_field_name).null |
|
594 filters = {reverse_field_name: self} |
|
595 for sub_obj in related.field.rel.through._base_manager.filter(**filters): |
|
596 sub_obj._collect_sub_objects(seen_objs, self, nullable) |
|
597 |
|
598 for f in self._meta.many_to_many: |
|
599 if f.rel.through: |
|
600 opts = f.rel.through._meta |
|
601 field_name = f.m2m_field_name() |
|
602 nullable = opts.get_field(field_name).null |
|
603 filters = {field_name: self} |
|
604 for sub_obj in f.rel.through._base_manager.filter(**filters): |
|
605 sub_obj._collect_sub_objects(seen_objs, self, nullable) |
|
606 else: |
|
607 # m2m-ish but with no through table? GenericRelation: cascade delete |
|
608 for sub_obj in f.value_from_object(self).all(): |
|
609 # Generic relations not enforced by db constraints, thus we can set |
|
610 # nullable=True, order does not matter |
|
611 sub_obj._collect_sub_objects(seen_objs, self, True) |
545 |
612 |
546 # Handle any ancestors (for the model-inheritance case). We do this by |
613 # Handle any ancestors (for the model-inheritance case). We do this by |
547 # traversing to the most remote parent classes -- those with no parents |
614 # traversing to the most remote parent classes -- those with no parents |
548 # themselves -- and then adding those instances to the collection. That |
615 # themselves -- and then adding those instances to the collection. That |
549 # will include all the child instances down to "self". |
616 # will include all the child instances down to "self". |
578 op = is_next and 'gt' or 'lt' |
647 op = is_next and 'gt' or 'lt' |
579 order = not is_next and '-' or '' |
648 order = not is_next and '-' or '' |
580 param = smart_str(getattr(self, field.attname)) |
649 param = smart_str(getattr(self, field.attname)) |
581 q = Q(**{'%s__%s' % (field.name, op): param}) |
650 q = Q(**{'%s__%s' % (field.name, op): param}) |
582 q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk}) |
651 q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk}) |
583 qs = self.__class__._default_manager.filter(**kwargs).filter(q).order_by('%s%s' % (order, field.name), '%spk' % order) |
652 qs = self.__class__._default_manager.using(self._state.db).filter(**kwargs).filter(q).order_by('%s%s' % (order, field.name), '%spk' % order) |
584 try: |
653 try: |
585 return qs[0] |
654 return qs[0] |
586 except IndexError: |
655 except IndexError: |
587 raise self.DoesNotExist, "%s matching query does not exist." % self.__class__._meta.object_name |
656 raise self.DoesNotExist("%s matching query does not exist." % self.__class__._meta.object_name) |
588 |
657 |
589 def _get_next_or_previous_in_order(self, is_next): |
658 def _get_next_or_previous_in_order(self, is_next): |
590 cachename = "__%s_order_cache" % is_next |
659 cachename = "__%s_order_cache" % is_next |
591 if not hasattr(self, cachename): |
660 if not hasattr(self, cachename): |
592 qn = connection.ops.quote_name |
661 op = is_next and 'gt' or 'lt' |
593 op = is_next and '>' or '<' |
|
594 order = not is_next and '-_order' or '_order' |
662 order = not is_next and '-_order' or '_order' |
595 order_field = self._meta.order_with_respect_to |
663 order_field = self._meta.order_with_respect_to |
596 # FIXME: When querysets support nested queries, this can be turned |
664 obj = self._default_manager.filter(**{ |
597 # into a pure queryset operation. |
665 order_field.name: getattr(self, order_field.attname) |
598 where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \ |
666 }).filter(**{ |
599 (qn('_order'), op, qn('_order'), |
667 '_order__%s' % op: self._default_manager.values('_order').filter(**{ |
600 qn(self._meta.db_table), qn(self._meta.pk.column))] |
668 self._meta.pk.name: self.pk |
601 params = [self.pk] |
669 }) |
602 obj = self._default_manager.filter(**{order_field.name: getattr(self, order_field.attname)}).extra(where=where, params=params).order_by(order)[:1].get() |
670 }).order_by(order)[:1].get() |
603 setattr(self, cachename, obj) |
671 setattr(self, cachename, obj) |
604 return getattr(self, cachename) |
672 return getattr(self, cachename) |
605 |
673 |
606 def prepare_database_save(self, unused): |
674 def prepare_database_save(self, unused): |
607 return self.pk |
675 return self.pk |
|
676 |
|
677 def clean(self): |
|
678 """ |
|
679 Hook for doing any extra model-wide validation after clean() has been |
|
680 called on every field by self.clean_fields. Any ValidationError raised |
|
681 by this method will not be associated with a particular field; it will |
|
682 have a special-case association with the field defined by NON_FIELD_ERRORS. |
|
683 """ |
|
684 pass |
|
685 |
|
686 def validate_unique(self, exclude=None): |
|
687 """ |
|
688 Checks unique constraints on the model and raises ``ValidationError`` |
|
689 if any failed. |
|
690 """ |
|
691 unique_checks, date_checks = self._get_unique_checks(exclude=exclude) |
|
692 |
|
693 errors = self._perform_unique_checks(unique_checks) |
|
694 date_errors = self._perform_date_checks(date_checks) |
|
695 |
|
696 for k, v in date_errors.items(): |
|
697 errors.setdefault(k, []).extend(v) |
|
698 |
|
699 if errors: |
|
700 raise ValidationError(errors) |
|
701 |
|
702 def _get_unique_checks(self, exclude=None): |
|
703 """ |
|
704 Gather a list of checks to perform. Since validate_unique could be |
|
705 called from a ModelForm, some fields may have been excluded; we can't |
|
706 perform a unique check on a model that is missing fields involved |
|
707 in that check. |
|
708 Fields that did not validate should also be exluded, but they need |
|
709 to be passed in via the exclude argument. |
|
710 """ |
|
711 if exclude is None: |
|
712 exclude = [] |
|
713 unique_checks = [] |
|
714 |
|
715 unique_togethers = [(self.__class__, self._meta.unique_together)] |
|
716 for parent_class in self._meta.parents.keys(): |
|
717 if parent_class._meta.unique_together: |
|
718 unique_togethers.append((parent_class, parent_class._meta.unique_together)) |
|
719 |
|
720 for model_class, unique_together in unique_togethers: |
|
721 for check in unique_together: |
|
722 for name in check: |
|
723 # If this is an excluded field, don't add this check. |
|
724 if name in exclude: |
|
725 break |
|
726 else: |
|
727 unique_checks.append((model_class, tuple(check))) |
|
728 |
|
729 # These are checks for the unique_for_<date/year/month>. |
|
730 date_checks = [] |
|
731 |
|
732 # Gather a list of checks for fields declared as unique and add them to |
|
733 # the list of checks. |
|
734 |
|
735 fields_with_class = [(self.__class__, self._meta.local_fields)] |
|
736 for parent_class in self._meta.parents.keys(): |
|
737 fields_with_class.append((parent_class, parent_class._meta.local_fields)) |
|
738 |
|
739 for model_class, fields in fields_with_class: |
|
740 for f in fields: |
|
741 name = f.name |
|
742 if name in exclude: |
|
743 continue |
|
744 if f.unique: |
|
745 unique_checks.append((model_class, (name,))) |
|
746 if f.unique_for_date: |
|
747 date_checks.append((model_class, 'date', name, f.unique_for_date)) |
|
748 if f.unique_for_year: |
|
749 date_checks.append((model_class, 'year', name, f.unique_for_year)) |
|
750 if f.unique_for_month: |
|
751 date_checks.append((model_class, 'month', name, f.unique_for_month)) |
|
752 return unique_checks, date_checks |
|
753 |
|
754 def _perform_unique_checks(self, unique_checks): |
|
755 errors = {} |
|
756 |
|
757 for model_class, unique_check in unique_checks: |
|
758 # Try to look up an existing object with the same values as this |
|
759 # object's values for all the unique field. |
|
760 |
|
761 lookup_kwargs = {} |
|
762 for field_name in unique_check: |
|
763 f = self._meta.get_field(field_name) |
|
764 lookup_value = getattr(self, f.attname) |
|
765 if lookup_value is None: |
|
766 # no value, skip the lookup |
|
767 continue |
|
768 if f.primary_key and not getattr(self, '_adding', False): |
|
769 # no need to check for unique primary key when editing |
|
770 continue |
|
771 lookup_kwargs[str(field_name)] = lookup_value |
|
772 |
|
773 # some fields were skipped, no reason to do the check |
|
774 if len(unique_check) != len(lookup_kwargs.keys()): |
|
775 continue |
|
776 |
|
777 qs = model_class._default_manager.filter(**lookup_kwargs) |
|
778 |
|
779 # Exclude the current object from the query if we are editing an |
|
780 # instance (as opposed to creating a new one) |
|
781 if not getattr(self, '_adding', False) and self.pk is not None: |
|
782 qs = qs.exclude(pk=self.pk) |
|
783 |
|
784 if qs.exists(): |
|
785 if len(unique_check) == 1: |
|
786 key = unique_check[0] |
|
787 else: |
|
788 key = NON_FIELD_ERRORS |
|
789 errors.setdefault(key, []).append(self.unique_error_message(model_class, unique_check)) |
|
790 |
|
791 return errors |
|
792 |
|
793 def _perform_date_checks(self, date_checks): |
|
794 errors = {} |
|
795 for model_class, lookup_type, field, unique_for in date_checks: |
|
796 lookup_kwargs = {} |
|
797 # there's a ticket to add a date lookup, we can remove this special |
|
798 # case if that makes it's way in |
|
799 date = getattr(self, unique_for) |
|
800 if lookup_type == 'date': |
|
801 lookup_kwargs['%s__day' % unique_for] = date.day |
|
802 lookup_kwargs['%s__month' % unique_for] = date.month |
|
803 lookup_kwargs['%s__year' % unique_for] = date.year |
|
804 else: |
|
805 lookup_kwargs['%s__%s' % (unique_for, lookup_type)] = getattr(date, lookup_type) |
|
806 lookup_kwargs[field] = getattr(self, field) |
|
807 |
|
808 qs = model_class._default_manager.filter(**lookup_kwargs) |
|
809 # Exclude the current object from the query if we are editing an |
|
810 # instance (as opposed to creating a new one) |
|
811 if not getattr(self, '_adding', False) and self.pk is not None: |
|
812 qs = qs.exclude(pk=self.pk) |
|
813 |
|
814 if qs.exists(): |
|
815 errors.setdefault(field, []).append( |
|
816 self.date_error_message(lookup_type, field, unique_for) |
|
817 ) |
|
818 return errors |
|
819 |
|
820 def date_error_message(self, lookup_type, field, unique_for): |
|
821 opts = self._meta |
|
822 return _(u"%(field_name)s must be unique for %(date_field)s %(lookup)s.") % { |
|
823 'field_name': unicode(capfirst(opts.get_field(field).verbose_name)), |
|
824 'date_field': unicode(capfirst(opts.get_field(unique_for).verbose_name)), |
|
825 'lookup': lookup_type, |
|
826 } |
|
827 |
|
828 def unique_error_message(self, model_class, unique_check): |
|
829 opts = model_class._meta |
|
830 model_name = capfirst(opts.verbose_name) |
|
831 |
|
832 # A unique field |
|
833 if len(unique_check) == 1: |
|
834 field_name = unique_check[0] |
|
835 field_label = capfirst(opts.get_field(field_name).verbose_name) |
|
836 # Insert the error into the error dict, very sneaky |
|
837 return _(u"%(model_name)s with this %(field_label)s already exists.") % { |
|
838 'model_name': unicode(model_name), |
|
839 'field_label': unicode(field_label) |
|
840 } |
|
841 # unique_together |
|
842 else: |
|
843 field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check) |
|
844 field_labels = get_text_list(field_labels, _('and')) |
|
845 return _(u"%(model_name)s with this %(field_label)s already exists.") % { |
|
846 'model_name': unicode(model_name), |
|
847 'field_label': unicode(field_labels) |
|
848 } |
|
849 |
|
850 def full_clean(self, exclude=None): |
|
851 """ |
|
852 Calls clean_fields, clean, and validate_unique, on the model, |
|
853 and raises a ``ValidationError`` for any errors that occured. |
|
854 """ |
|
855 errors = {} |
|
856 if exclude is None: |
|
857 exclude = [] |
|
858 |
|
859 try: |
|
860 self.clean_fields(exclude=exclude) |
|
861 except ValidationError, e: |
|
862 errors = e.update_error_dict(errors) |
|
863 |
|
864 # Form.clean() is run even if other validation fails, so do the |
|
865 # same with Model.clean() for consistency. |
|
866 try: |
|
867 self.clean() |
|
868 except ValidationError, e: |
|
869 errors = e.update_error_dict(errors) |
|
870 |
|
871 # Run unique checks, but only for fields that passed validation. |
|
872 for name in errors.keys(): |
|
873 if name != NON_FIELD_ERRORS and name not in exclude: |
|
874 exclude.append(name) |
|
875 try: |
|
876 self.validate_unique(exclude=exclude) |
|
877 except ValidationError, e: |
|
878 errors = e.update_error_dict(errors) |
|
879 |
|
880 if errors: |
|
881 raise ValidationError(errors) |
|
882 |
|
883 def clean_fields(self, exclude=None): |
|
884 """ |
|
885 Cleans all fields and raises a ValidationError containing message_dict |
|
886 of all validation errors if any occur. |
|
887 """ |
|
888 if exclude is None: |
|
889 exclude = [] |
|
890 |
|
891 errors = {} |
|
892 for f in self._meta.fields: |
|
893 if f.name in exclude: |
|
894 continue |
|
895 # Skip validation for empty fields with blank=True. The developer |
|
896 # is responsible for making sure they have a valid value. |
|
897 raw_value = getattr(self, f.attname) |
|
898 if f.blank and raw_value in validators.EMPTY_VALUES: |
|
899 continue |
|
900 try: |
|
901 setattr(self, f.attname, f.clean(raw_value, self)) |
|
902 except ValidationError, e: |
|
903 errors[f.name] = e.messages |
|
904 |
|
905 if errors: |
|
906 raise ValidationError(errors) |
608 |
907 |
609 |
908 |
610 ############################################ |
909 ############################################ |
611 # HELPER FUNCTIONS (CURRIED MODEL METHODS) # |
910 # HELPER FUNCTIONS (CURRIED MODEL METHODS) # |
612 ############################################ |
911 ############################################ |
613 |
912 |
614 # ORDERING METHODS ######################### |
913 # ORDERING METHODS ######################### |
615 |
914 |
616 def method_set_order(ordered_obj, self, id_list): |
915 def method_set_order(ordered_obj, self, id_list, using=None): |
|
916 if using is None: |
|
917 using = DEFAULT_DB_ALIAS |
617 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |
918 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |
618 order_name = ordered_obj._meta.order_with_respect_to.name |
919 order_name = ordered_obj._meta.order_with_respect_to.name |
619 # FIXME: It would be nice if there was an "update many" version of update |
920 # FIXME: It would be nice if there was an "update many" version of update |
620 # for situations like this. |
921 # for situations like this. |
621 for i, j in enumerate(id_list): |
922 for i, j in enumerate(id_list): |
622 ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) |
923 ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) |
623 transaction.commit_unless_managed() |
924 transaction.commit_unless_managed(using=using) |
624 |
925 |
625 |
926 |
626 def method_get_order(ordered_obj, self): |
927 def method_get_order(ordered_obj, self): |
627 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |
928 rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) |
628 order_name = ordered_obj._meta.order_with_respect_to.name |
929 order_name = ordered_obj._meta.order_with_respect_to.name |