1
0
mirror of https://github.com/django/django.git synced 2024-12-30 21:16:26 +00:00
django/tests/admin_inlines/models.py
Mariusz Felisiak 445b075def
Fixed #33547 -- Fixed error when rendering invalid inlines with readonly fields in admin.
Regression in de95c82667.

Thanks David Glenck for the report.
2022-03-01 08:09:58 +01:00

380 lines
9.1 KiB
Python

"""
Testing of admin inline formsets.
"""
import random
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import models
class Parent(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Teacher(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Child(models.Model):
name = models.CharField(max_length=50)
teacher = models.ForeignKey(Teacher, models.CASCADE)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
parent = GenericForeignKey()
def __str__(self):
return "I am %s, a child of %s" % (self.name, self.parent)
class Book(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
books = models.ManyToManyField(Book)
person = models.OneToOneField("Person", models.CASCADE, null=True)
class NonAutoPKBook(models.Model):
rand_pk = models.IntegerField(primary_key=True, editable=False)
author = models.ForeignKey(Author, models.CASCADE)
title = models.CharField(max_length=50)
def save(self, *args, **kwargs):
while not self.rand_pk:
test_pk = random.randint(1, 99999)
if not NonAutoPKBook.objects.filter(rand_pk=test_pk).exists():
self.rand_pk = test_pk
super().save(*args, **kwargs)
class NonAutoPKBookChild(NonAutoPKBook):
pass
class EditablePKBook(models.Model):
manual_pk = models.IntegerField(primary_key=True)
author = models.ForeignKey(Author, models.CASCADE)
title = models.CharField(max_length=50)
class Holder(models.Model):
dummy = models.IntegerField()
class Inner(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder, models.CASCADE)
readonly = models.CharField("Inner readonly label", max_length=1)
def get_absolute_url(self):
return "/inner/"
class Holder2(models.Model):
dummy = models.IntegerField()
class Inner2(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder2, models.CASCADE)
class Holder3(models.Model):
dummy = models.IntegerField()
class Inner3(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder3, models.CASCADE)
# Models for ticket #8190
class Holder4(models.Model):
dummy = models.IntegerField()
class Inner4Stacked(models.Model):
dummy = models.IntegerField(help_text="Awesome stacked help text is awesome.")
holder = models.ForeignKey(Holder4, models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["dummy", "holder"], name="unique_stacked_dummy_per_holder"
)
]
class Inner4Tabular(models.Model):
dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
holder = models.ForeignKey(Holder4, models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["dummy", "holder"], name="unique_tabular_dummy_per_holder"
)
]
# Models for ticket #31441
class Holder5(models.Model):
dummy = models.IntegerField()
class Inner5Stacked(models.Model):
name = models.CharField(max_length=10)
select = models.CharField(choices=(("1", "One"), ("2", "Two")), max_length=10)
text = models.TextField()
dummy = models.IntegerField()
holder = models.ForeignKey(Holder5, models.CASCADE)
class Inner5Tabular(models.Model):
name = models.CharField(max_length=10)
select = models.CharField(choices=(("1", "One"), ("2", "Two")), max_length=10)
text = models.TextField()
dummy = models.IntegerField()
holder = models.ForeignKey(Holder5, models.CASCADE)
# Models for #12749
class Person(models.Model):
firstname = models.CharField(max_length=15)
class OutfitItem(models.Model):
name = models.CharField(max_length=15)
class Fashionista(models.Model):
person = models.OneToOneField(Person, models.CASCADE, primary_key=True)
weaknesses = models.ManyToManyField(
OutfitItem, through="ShoppingWeakness", blank=True
)
class ShoppingWeakness(models.Model):
fashionista = models.ForeignKey(Fashionista, models.CASCADE)
item = models.ForeignKey(OutfitItem, models.CASCADE)
# Models for #13510
class TitleCollection(models.Model):
pass
class Title(models.Model):
collection = models.ForeignKey(
TitleCollection, models.SET_NULL, blank=True, null=True
)
title1 = models.CharField(max_length=100)
title2 = models.CharField(max_length=100)
# Models for #15424
class Poll(models.Model):
name = models.CharField(max_length=40)
class Question(models.Model):
text = models.CharField(max_length=40)
poll = models.ForeignKey(Poll, models.CASCADE)
def clean(self):
raise ValidationError("Always invalid model.")
class Novel(models.Model):
name = models.CharField(max_length=40)
class NovelReadonlyChapter(Novel):
class Meta:
proxy = True
class Chapter(models.Model):
name = models.CharField(max_length=40)
novel = models.ForeignKey(Novel, models.CASCADE)
class FootNote(models.Model):
"""
Model added for ticket 19838
"""
chapter = models.ForeignKey(Chapter, models.PROTECT)
note = models.CharField(max_length=40)
# Models for #16838
class CapoFamiglia(models.Model):
name = models.CharField(max_length=100)
class Consigliere(models.Model):
name = models.CharField(max_length=100, help_text="Help text for Consigliere")
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE, related_name="+")
class SottoCapo(models.Model):
name = models.CharField(max_length=100)
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE, related_name="+")
class ReadOnlyInline(models.Model):
name = models.CharField(max_length=100, help_text="Help text for ReadOnlyInline")
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE)
# Models for #18433
class ParentModelWithCustomPk(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
class ChildModel1(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self):
return "/child_model1/"
class ChildModel2(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self):
return "/child_model2/"
# Models for #19425
class BinaryTree(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey("self", models.SET_NULL, null=True, blank=True)
# Models for #19524
class LifeForm(models.Model):
pass
class ExtraTerrestrial(LifeForm):
name = models.CharField(max_length=100)
class Sighting(models.Model):
et = models.ForeignKey(ExtraTerrestrial, models.CASCADE)
place = models.CharField(max_length=100)
# Models for #18263
class SomeParentModel(models.Model):
name = models.CharField(max_length=1)
class SomeChildModel(models.Model):
name = models.CharField(max_length=1)
position = models.PositiveIntegerField()
parent = models.ForeignKey(SomeParentModel, models.CASCADE)
readonly_field = models.CharField(max_length=1)
# Models for #30231
class Course(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Class(models.Model):
person = models.ManyToManyField(Person, verbose_name="attendant")
course = models.ForeignKey(Course, on_delete=models.CASCADE)
class CourseProxy(Course):
class Meta:
proxy = True
class CourseProxy1(Course):
class Meta:
proxy = True
class CourseProxy2(Course):
class Meta:
proxy = True
# Other models
class ShowInlineParent(models.Model):
show_inlines = models.BooleanField(default=False)
class ShowInlineChild(models.Model):
parent = models.ForeignKey(ShowInlineParent, on_delete=models.CASCADE)
class ProfileCollection(models.Model):
pass
class Profile(models.Model):
collection = models.ForeignKey(
ProfileCollection, models.SET_NULL, blank=True, null=True
)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class VerboseNameProfile(Profile):
class Meta:
verbose_name = "Model with verbose name only"
class VerboseNamePluralProfile(Profile):
class Meta:
verbose_name_plural = "Model with verbose name plural only"
class BothVerboseNameProfile(Profile):
class Meta:
verbose_name = "Model with both - name"
verbose_name_plural = "Model with both - plural name"