123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- """
- XX. Generating HTML forms from models
- This is mostly just a reworking of the ``form_for_model``/``form_for_instance``
- tests to use ``ModelForm``. As such, the text may not make sense in all cases,
- and the examples are probably a poor fit for the ``ModelForm`` syntax. In other
- words, most of these tests should be rewritten.
- """
- from __future__ import unicode_literals
- import datetime
- import os
- import tempfile
- from django.core import validators
- from django.core.exceptions import ValidationError
- from django.core.files.storage import FileSystemStorage
- from django.db import models
- from django.utils import six
- from django.utils.encoding import python_2_unicode_compatible
- from django.utils._os import upath
- temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
- temp_storage = FileSystemStorage(temp_storage_dir)
- ARTICLE_STATUS = (
- (1, 'Draft'),
- (2, 'Pending'),
- (3, 'Live'),
- )
- ARTICLE_STATUS_CHAR = (
- ('d', 'Draft'),
- ('p', 'Pending'),
- ('l', 'Live'),
- )
- class Person(models.Model):
- name = models.CharField(max_length=100)
- @python_2_unicode_compatible
- class Category(models.Model):
- name = models.CharField(max_length=20)
- slug = models.SlugField(max_length=20)
- url = models.CharField('The URL', max_length=40)
- def __str__(self):
- return self.name
- def __repr__(self):
- return self.__str__()
- @python_2_unicode_compatible
- class Writer(models.Model):
- name = models.CharField(max_length=50, help_text='Use both first and last names.')
- class Meta:
- ordering = ('name',)
- def __str__(self):
- return self.name
- @python_2_unicode_compatible
- class Article(models.Model):
- headline = models.CharField(max_length=50)
- slug = models.SlugField()
- pub_date = models.DateField()
- created = models.DateField(editable=False)
- writer = models.ForeignKey(Writer)
- article = models.TextField()
- categories = models.ManyToManyField(Category, blank=True)
- status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True)
- def save(self, *args, **kwargs):
- if not self.id:
- self.created = datetime.date.today()
- return super(Article, self).save(*args, **kwargs)
- def __str__(self):
- return self.headline
- class ImprovedArticle(models.Model):
- article = models.OneToOneField(Article)
- class ImprovedArticleWithParentLink(models.Model):
- article = models.OneToOneField(Article, parent_link=True)
- class BetterWriter(Writer):
- score = models.IntegerField()
- @python_2_unicode_compatible
- class Publication(models.Model):
- title = models.CharField(max_length=30)
- date_published = models.DateField()
- def __str__(self):
- return self.title
- class Author(models.Model):
- publication = models.OneToOneField(Publication, null=True, blank=True)
- full_name = models.CharField(max_length=255)
- class Author1(models.Model):
- publication = models.OneToOneField(Publication, null=False)
- full_name = models.CharField(max_length=255)
- @python_2_unicode_compatible
- class WriterProfile(models.Model):
- writer = models.OneToOneField(Writer, primary_key=True)
- age = models.PositiveIntegerField()
- def __str__(self):
- return "%s is %s" % (self.writer, self.age)
- class Document(models.Model):
- myfile = models.FileField(upload_to='unused', blank=True)
- @python_2_unicode_compatible
- class TextFile(models.Model):
- description = models.CharField(max_length=20)
- file = models.FileField(storage=temp_storage, upload_to='tests', max_length=15)
- def __str__(self):
- return self.description
- class CustomFileField(models.FileField):
- def save_form_data(self, instance, data):
- been_here = getattr(self, 'been_saved', False)
- assert not been_here, "save_form_data called more than once"
- setattr(self, 'been_saved', True)
- class CustomFF(models.Model):
- f = CustomFileField(upload_to='unused', blank=True)
- class FilePathModel(models.Model):
- path = models.FilePathField(path=os.path.dirname(upath(__file__)), match=".*\.py$", blank=True)
- try:
- from PIL import Image # NOQA: detect if Pillow is installed
- test_images = True
- @python_2_unicode_compatible
- class ImageFile(models.Model):
- def custom_upload_path(self, filename):
- path = self.path or 'tests'
- return '%s/%s' % (path, filename)
- description = models.CharField(max_length=20)
- # Deliberately put the image field *after* the width/height fields to
- # trigger the bug in #10404 with width/height not getting assigned.
- width = models.IntegerField(editable=False)
- height = models.IntegerField(editable=False)
- image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path,
- width_field='width', height_field='height')
- path = models.CharField(max_length=16, blank=True, default='')
- def __str__(self):
- return self.description
- @python_2_unicode_compatible
- class OptionalImageFile(models.Model):
- def custom_upload_path(self, filename):
- path = self.path or 'tests'
- return '%s/%s' % (path, filename)
- description = models.CharField(max_length=20)
- image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path,
- width_field='width', height_field='height',
- blank=True, null=True)
- width = models.IntegerField(editable=False, null=True)
- height = models.IntegerField(editable=False, null=True)
- path = models.CharField(max_length=16, blank=True, default='')
- def __str__(self):
- return self.description
- except ImportError:
- test_images = False
- @python_2_unicode_compatible
- class CommaSeparatedInteger(models.Model):
- field = models.CommaSeparatedIntegerField(max_length=20)
- def __str__(self):
- return self.field
- class Homepage(models.Model):
- url = models.URLField()
- @python_2_unicode_compatible
- class Product(models.Model):
- slug = models.SlugField(unique=True)
- def __str__(self):
- return self.slug
- @python_2_unicode_compatible
- class Price(models.Model):
- price = models.DecimalField(max_digits=10, decimal_places=2)
- quantity = models.PositiveIntegerField()
- def __str__(self):
- return "%s for %s" % (self.quantity, self.price)
- class Meta:
- unique_together = (('price', 'quantity'),)
- class Triple(models.Model):
- left = models.IntegerField()
- middle = models.IntegerField()
- right = models.IntegerField()
- class Meta:
- unique_together = (('left', 'middle'), ('middle', 'right'))
- class ArticleStatus(models.Model):
- status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True)
- @python_2_unicode_compatible
- class Inventory(models.Model):
- barcode = models.PositiveIntegerField(unique=True)
- parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True)
- name = models.CharField(blank=False, max_length=20)
- class Meta:
- ordering = ('name',)
- def __str__(self):
- return self.name
- def __repr__(self):
- return self.__str__()
- class Book(models.Model):
- title = models.CharField(max_length=40)
- author = models.ForeignKey(Writer, blank=True, null=True)
- special_id = models.IntegerField(blank=True, null=True, unique=True)
- class Meta:
- unique_together = ('title', 'author')
- class BookXtra(models.Model):
- isbn = models.CharField(max_length=16, unique=True)
- suffix1 = models.IntegerField(blank=True, default=0)
- suffix2 = models.IntegerField(blank=True, default=0)
- class Meta:
- unique_together = (('suffix1', 'suffix2'))
- abstract = True
- class DerivedBook(Book, BookXtra):
- pass
- @python_2_unicode_compatible
- class ExplicitPK(models.Model):
- key = models.CharField(max_length=20, primary_key=True)
- desc = models.CharField(max_length=20, blank=True, unique=True)
- class Meta:
- unique_together = ('key', 'desc')
- def __str__(self):
- return self.key
- @python_2_unicode_compatible
- class Post(models.Model):
- title = models.CharField(max_length=50, unique_for_date='posted', blank=True)
- slug = models.CharField(max_length=50, unique_for_year='posted', blank=True)
- subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True)
- posted = models.DateField()
- def __str__(self):
- return self.title
- @python_2_unicode_compatible
- class DateTimePost(models.Model):
- title = models.CharField(max_length=50, unique_for_date='posted', blank=True)
- slug = models.CharField(max_length=50, unique_for_year='posted', blank=True)
- subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True)
- posted = models.DateTimeField(editable=False)
- def __str__(self):
- return self.title
- class DerivedPost(Post):
- pass
- @python_2_unicode_compatible
- class BigInt(models.Model):
- biggie = models.BigIntegerField()
- def __str__(self):
- return six.text_type(self.biggie)
- class MarkupField(models.CharField):
- def __init__(self, *args, **kwargs):
- kwargs["max_length"] = 20
- super(MarkupField, self).__init__(*args, **kwargs)
- def formfield(self, **kwargs):
- # don't allow this field to be used in form (real use-case might be
- # that you know the markup will always be X, but it is among an app
- # that allows the user to say it could be something else)
- # regressed at r10062
- return None
- class CustomFieldForExclusionModel(models.Model):
- name = models.CharField(max_length=10)
- markup = MarkupField()
- class FlexibleDatePost(models.Model):
- title = models.CharField(max_length=50, unique_for_date='posted', blank=True)
- slug = models.CharField(max_length=50, unique_for_year='posted', blank=True)
- subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True)
- posted = models.DateField(blank=True, null=True)
- @python_2_unicode_compatible
- class Colour(models.Model):
- name = models.CharField(max_length=50)
- def __iter__(self):
- for number in xrange(5):
- yield number
- def __str__(self):
- return self.name
- class ColourfulItem(models.Model):
- name = models.CharField(max_length=50)
- colours = models.ManyToManyField(Colour)
- class ArticleStatusNote(models.Model):
- name = models.CharField(max_length=20)
- status = models.ManyToManyField(ArticleStatus)
- class CustomErrorMessage(models.Model):
- name1 = models.CharField(max_length=50,
- validators=[validators.validate_slug],
- error_messages={'invalid': 'Model custom error message.'})
- name2 = models.CharField(max_length=50,
- validators=[validators.validate_slug],
- error_messages={'invalid': 'Model custom error message.'})
- def clean(self):
- if self.name1 == 'FORBIDDEN_VALUE':
- raise ValidationError({'name1': [ValidationError('Model.clean() error messages.')]})
- elif self.name1 == 'GLOBAL_ERROR':
- raise ValidationError("Global error message.")
- def today_callable_dict():
- return {"last_action__gte": datetime.datetime.today()}
- def today_callable_q():
- return models.Q(last_action__gte=datetime.datetime.today())
- class Character(models.Model):
- username = models.CharField(max_length=100)
- last_action = models.DateTimeField()
- class StumpJoke(models.Model):
- most_recently_fooled = models.ForeignKey(Character, limit_choices_to=today_callable_dict, related_name="+")
- has_fooled_today = models.ManyToManyField(Character, limit_choices_to=today_callable_q, related_name="+")
|