Django

Code

root/django/trunk/tests/modeltests/invalid_models/models.py

Revision 8616, 21.6 kB (checked in by gwilson, 2 weeks ago)

Removed oldforms, validators, and related code:

  • Removed Manipulator, AutomaticManipulator, and related classes.
  • Removed oldforms specific bits from model fields:
    • Removed validator_list and core arguments from constructors.
    • Removed the methods:
      • get_manipulator_field_names
      • get_manipulator_field_objs
      • get_manipulator_fields
      • get_manipulator_new_data
      • prepare_field_objs_and_params
      • get_follow
    • Renamed flatten_data method to value_to_string for better alignment with its use by the serialization framework, which was the only remaining code using flatten_data.
  • Removed oldforms methods from django.db.models.Options class: get_followed_related_objects, get_data_holders, get_follow, and has_field_type.
  • Removed oldforms-admin specific options from django.db.models.fields.related classes: num_in_admin, min_num_in_admin, max_num_in_admin, num_extra_on_change, and edit_inline.
  • Serialization framework
    • Serializer.get_string_value now calls the model fields' renamed value_to_string methods.
    • Removed a special-casing of models.DateTimeField in core.serializers.base.Serializer.get_string_value that's handled by django.db.models.fields.DateTimeField.value_to_string.
  • Removed django.core.validators:
    • Moved ValidationError exception to django.core.exceptions.
    • For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
  • Introduced a SlugField? form field for validation and to compliment the SlugField? model field (refs #8040).
  • Removed an oldforms-style model creation hack (refs #2160).
  • Property svn:eol-style set to native
Line 
1 """
2 26. Invalid models
3
4 This example exists purely to point out errors in models.
5 """
6
7 from django.db import models
8
9 class FieldErrors(models.Model):
10     charfield = models.CharField()
11     decimalfield = models.DecimalField()
12     filefield = models.FileField()
13     choices = models.CharField(max_length=10, choices='bad')
14     choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)])
15     index = models.CharField(max_length=10, db_index='bad')
16     field_ = models.CharField(max_length=10)
17
18 class Target(models.Model):
19     tgt_safe = models.CharField(max_length=10)
20     clash1 = models.CharField(max_length=10)
21     clash2 = models.CharField(max_length=10)
22
23     clash1_set = models.CharField(max_length=10)
24
25 class Clash1(models.Model):
26     src_safe = models.CharField(max_length=10)
27
28     foreign = models.ForeignKey(Target)
29     m2m = models.ManyToManyField(Target)
30
31 class Clash2(models.Model):
32     src_safe = models.CharField(max_length=10)
33
34     foreign_1 = models.ForeignKey(Target, related_name='id')
35     foreign_2 = models.ForeignKey(Target, related_name='src_safe')
36
37     m2m_1 = models.ManyToManyField(Target, related_name='id')
38     m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
39
40 class Target2(models.Model):
41     clash3 = models.CharField(max_length=10)
42     foreign_tgt = models.ForeignKey(Target)
43     clashforeign_set = models.ForeignKey(Target)
44
45     m2m_tgt = models.ManyToManyField(Target)
46     clashm2m_set = models.ManyToManyField(Target)
47
48 class Clash3(models.Model):
49     src_safe = models.CharField(max_length=10)
50
51     foreign_1 = models.ForeignKey(Target2, related_name='foreign_tgt')
52     foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt')
53
54     m2m_1 = models.ManyToManyField(Target2, related_name='foreign_tgt')
55     m2m_2 = models.ManyToManyField(Target2, related_name='m2m_tgt')
56
57 class ClashForeign(models.Model):
58     foreign = models.ForeignKey(Target2)
59
60 class ClashM2M(models.Model):
61     m2m = models.ManyToManyField(Target2)
62
63 class SelfClashForeign(models.Model):
64     src_safe = models.CharField(max_length=10)
65     selfclashforeign = models.CharField(max_length=10)
66
67     selfclashforeign_set = models.ForeignKey("SelfClashForeign")
68     foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id')
69     foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe')
70
71 class ValidM2M(models.Model):
72     src_safe = models.CharField(max_length=10)
73     validm2m = models.CharField(max_length=10)
74
75     # M2M fields are symmetrical by default. Symmetrical M2M fields
76     # on self don't require a related accessor, so many potential
77     # clashes are avoided.
78     validm2m_set = models.ManyToManyField("ValidM2M")
79
80     m2m_1 = models.ManyToManyField("ValidM2M", related_name='id')
81     m2m_2 = models.ManyToManyField("ValidM2M", related_name='src_safe')
82
83     m2m_3 = models.ManyToManyField('self')
84     m2m_4 = models.ManyToManyField('self')
85
86 class SelfClashM2M(models.Model):
87     src_safe = models.CharField(max_length=10)
88     selfclashm2m = models.CharField(max_length=10)
89
90     # Non-symmetrical M2M fields _do_ have related accessors, so
91     # there is potential for clashes.
92     selfclashm2m_set = models.ManyToManyField("SelfClashM2M", symmetrical=False)
93
94     m2m_1 = models.ManyToManyField("SelfClashM2M", related_name='id', symmetrical=False)
95     m2m_2 = models.ManyToManyField("SelfClashM2M", related_name='src_safe', symmetrical=False)
96
97     m2m_3 = models.ManyToManyField('self', symmetrical=False)
98     m2m_4 = models.ManyToManyField('self', symmetrical=False)
99
100 class Model(models.Model):
101     "But it's valid to call a model Model."
102     year = models.PositiveIntegerField() #1960
103     make = models.CharField(max_length=10) #Aston Martin
104     name = models.CharField(max_length=10) #DB 4 GT
105
106 class Car(models.Model):
107     colour = models.CharField(max_length=5)
108     model = models.ForeignKey(Model)
109
110 class MissingRelations(models.Model):
111     rel1 = models.ForeignKey("Rel1")
112     rel2 = models.ManyToManyField("Rel2")
113
114 class MissingManualM2MModel(models.Model):
115     name = models.CharField(max_length=5)
116     missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
117
118 class Person(models.Model):
119     name = models.CharField(max_length=5)
120
121 class Group(models.Model):
122     name = models.CharField(max_length=5)
123     primary = models.ManyToManyField(Person, through="Membership", related_name="primary")
124     secondary = models.ManyToManyField(Person, through="Membership", related_name="secondary")
125     tertiary = models.ManyToManyField(Person, through="RelationshipDoubleFK", related_name="tertiary")
126
127 class GroupTwo(models.Model):
128     name = models.CharField(max_length=5)
129     primary = models.ManyToManyField(Person, through="Membership")
130     secondary = models.ManyToManyField(Group, through="MembershipMissingFK")
131
132 class Membership(models.Model):
133     person = models.ForeignKey(Person)
134     group = models.ForeignKey(Group)
135     not_default_or_null = models.CharField(max_length=5)
136
137 class MembershipMissingFK(models.Model):
138     person = models.ForeignKey(Person)
139
140 class PersonSelfRefM2M(models.Model):
141     name = models.CharField(max_length=5)
142     friends = models.ManyToManyField('self', through="Relationship")
143     too_many_friends = models.ManyToManyField('self', through="RelationshipTripleFK")
144
145 class PersonSelfRefM2MExplicit(models.Model):
146     name = models.CharField(max_length=5)
147     friends = models.ManyToManyField('self', through="ExplicitRelationship", symmetrical=True)
148
149 class Relationship(models.Model):
150     first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
151     second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
152     date_added = models.DateTimeField()
153
154 class ExplicitRelationship(models.Model):
155     first = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_from_set")
156     second = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_to_set")
157     date_added = models.DateTimeField()
158
159 class RelationshipTripleFK(models.Model):
160     first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set_2")
161     second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set_2")
162     third = models.ForeignKey(PersonSelfRefM2M, related_name="too_many_by_far")
163     date_added = models.DateTimeField()
164
165 class RelationshipDoubleFK(models.Model):
166     first = models.ForeignKey(Person, related_name="first_related_name")
167     second = models.ForeignKey(Person, related_name="second_related_name")
168     third = models.ForeignKey(Group, related_name="rel_to_set")
169     date_added = models.DateTimeField()
170
171 class AbstractModel(models.Model):
172     name = models.CharField(max_length=10)
173     class Meta:
174         abstract = True
175
176 class AbstractRelationModel(models.Model):
177     fk1 = models.ForeignKey('AbstractModel')
178     fk2 = models.ManyToManyField('AbstractModel')
179
180 class UniqueM2M(models.Model):
181     """ Model to test for unique ManyToManyFields, which are invalid. """
182     unique_people = models.ManyToManyField( Person, unique=True )
183
184 model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
185 invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
186 invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
187 invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
188 invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list).
189 invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples.
190 invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples.
191 invalid_models.fielderrors: "index": "db_index" should be either None, True or False.
192 invalid_models.fielderrors: "field_": Field names cannot end with underscores, because this would lead to ambiguous queryset filters.
193 invalid_models.clash1: Accessor for field 'foreign' clashes with field 'Target.clash1_set'. Add a related_name argument to the definition for 'foreign'.
194 invalid_models.clash1: Accessor for field 'foreign' clashes with related m2m field 'Target.clash1_set'. Add a related_name argument to the definition for 'foreign'.
195 invalid_models.clash1: Reverse query name for field 'foreign' clashes with field 'Target.clash1'. Add a related_name argument to the definition for 'foreign'.
196 invalid_models.clash1: Accessor for m2m field 'm2m' clashes with field 'Target.clash1_set'. Add a related_name argument to the definition for 'm2m'.
197 invalid_models.clash1: Accessor for m2m field 'm2m' clashes with related field 'Target.clash1_set'. Add a related_name argument to the definition for 'm2m'.
198 invalid_models.clash1: Reverse query name for m2m field 'm2m' clashes with field 'Target.clash1'. Add a related_name argument to the definition for 'm2m'.
199 invalid_models.clash2: Accessor for field 'foreign_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'.
200 invalid_models.clash2: Accessor for field 'foreign_1' clashes with related m2m field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'.
201 invalid_models.clash2: Reverse query name for field 'foreign_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'.
202 invalid_models.clash2: Reverse query name for field 'foreign_1' clashes with related m2m field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'.
203 invalid_models.clash2: Accessor for field 'foreign_2' clashes with related m2m field 'Target.src_safe'. Add a related_name argument to the definition for 'foreign_2'.
204 invalid_models.clash2: Reverse query name for field 'foreign_2' clashes with related m2m field 'Target.src_safe'. Add a related_name argument to the definition for 'foreign_2'.
205 invalid_models.clash2: Accessor for m2m field 'm2m_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'.
206 invalid_models.clash2: Accessor for m2m field 'm2m_1' clashes with related field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'.
207 invalid_models.clash2: Reverse query name for m2m field 'm2m_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'.
208 invalid_models.clash2: Reverse query name for m2m field 'm2m_1' clashes with related field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'.
209 invalid_models.clash2: Accessor for m2m field 'm2m_2' clashes with related field 'Target.src_safe'. Add a related_name argument to the definition for 'm2m_2'.
210 invalid_models.clash2: Reverse query name for m2m field 'm2m_2' clashes with related field 'Target.src_safe'. Add a related_name argument to the definition for 'm2m_2'.
211 invalid_models.clash3: Accessor for field 'foreign_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'.
212 invalid_models.clash3: Accessor for field 'foreign_1' clashes with related m2m field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'.
213 invalid_models.clash3: Reverse query name for field 'foreign_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'.
214 invalid_models.clash3: Reverse query name for field 'foreign_1' clashes with related m2m field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'.
215 invalid_models.clash3: Accessor for field 'foreign_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'.
216 invalid_models.clash3: Accessor for field 'foreign_2' clashes with related m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'.
217 invalid_models.clash3: Reverse query name for field 'foreign_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'.
218 invalid_models.clash3: Reverse query name for field 'foreign_2' clashes with related m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'.
219 invalid_models.clash3: Accessor for m2m field 'm2m_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'.
220 invalid_models.clash3: Accessor for m2m field 'm2m_1' clashes with related field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'.
221 invalid_models.clash3: Reverse query name for m2m field 'm2m_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'.
222 invalid_models.clash3: Reverse query name for m2m field 'm2m_1' clashes with related field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'.
223 invalid_models.clash3: Accessor for m2m field 'm2m_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'.
224 invalid_models.clash3: Accessor for m2m field 'm2m_2' clashes with related field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'.
225 invalid_models.clash3: Reverse query name for m2m field 'm2m_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'.
226 invalid_models.clash3: Reverse query name for m2m field 'm2m_2' clashes with related field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'.
227 invalid_models.clashforeign: Accessor for field 'foreign' clashes with field 'Target2.clashforeign_set'. Add a related_name argument to the definition for 'foreign'.
228 invalid_models.clashm2m: Accessor for m2m field 'm2m' clashes with m2m field 'Target2.clashm2m_set'. Add a related_name argument to the definition for 'm2m'.
229 invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'.
230 invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'.
231 invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'.
232 invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'.
233 invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'.
234 invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'.
235 invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'.
236 invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'.
237 invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'.
238 invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'.
239 invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'.
240 invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'.
241 invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'.
242 invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'.
243 invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'.
244 invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'.
245 invalid_models.selfclashforeign: Accessor for field 'selfclashforeign_set' clashes with field 'SelfClashForeign.selfclashforeign_set'. Add a related_name argument to the definition for 'selfclashforeign_set'.
246 invalid_models.selfclashforeign: Reverse query name for field 'selfclashforeign_set' clashes with field 'SelfClashForeign.selfclashforeign'. Add a related_name argument to the definition for 'selfclashforeign_set'.
247 invalid_models.selfclashforeign: Accessor for field 'foreign_1' clashes with field 'SelfClashForeign.id'. Add a related_name argument to the definition for 'foreign_1'.
248 invalid_models.selfclashforeign: Reverse query name for field 'foreign_1' clashes with field 'SelfClashForeign.id'. Add a related_name argument to the definition for 'foreign_1'.
249 invalid_models.selfclashforeign: Accessor for field 'foreign_2' clashes with field 'SelfClashForeign.src_safe'. Add a related_name argument to the definition for 'foreign_2'.
250 invalid_models.selfclashforeign: Reverse query name for field 'foreign_2' clashes with field 'SelfClashForeign.src_safe'. Add a related_name argument to the definition for 'foreign_2'.
251 invalid_models.selfclashm2m: Accessor for m2m field 'selfclashm2m_set' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'selfclashm2m_set'.
252 invalid_models.selfclashm2m: Reverse query name for m2m field 'selfclashm2m_set' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'selfclashm2m_set'.
253 invalid_models.selfclashm2m: Accessor for m2m field 'selfclashm2m_set' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'selfclashm2m_set'.
254 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_1' clashes with field 'SelfClashM2M.id'. Add a related_name argument to the definition for 'm2m_1'.
255 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_2' clashes with field 'SelfClashM2M.src_safe'. Add a related_name argument to the definition for 'm2m_2'.
256 invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_1' clashes with field 'SelfClashM2M.id'. Add a related_name argument to the definition for 'm2m_1'.
257 invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_2' clashes with field 'SelfClashM2M.src_safe'. Add a related_name argument to the definition for 'm2m_2'.
258 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'.
259 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'.
260 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'.
261 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'.
262 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'.
263 invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'.
264 invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_3'.
265 invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_4' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_4'.
266 invalid_models.missingrelations: 'rel1' has a relation with model Rel1, which has either not been installed or is abstract.
267 invalid_models.missingrelations: 'rel2' has an m2m relation with model Rel2, which has either not been installed or is abstract.
268 invalid_models.grouptwo: 'primary' has a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo
269 invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo
270 invalid_models.missingmanualm2mmodel: 'missing_m2m' specifies an m2m relation through model MissingM2MModel, which has not been installed
271 invalid_models.group: The model Group has two manually-defined m2m relations through the model Membership, which is not permitted. Please consider using an extra field on your intermediary model instead.
272 invalid_models.group: Intermediary model RelationshipDoubleFK has more than one foreign key to Person, which is ambiguous and is not permitted.
273 invalid_models.personselfrefm2m: Many-to-many fields with intermediate tables cannot be symmetrical.
274 invalid_models.personselfrefm2m: Intermediary model RelationshipTripleFK has more than two foreign keys to PersonSelfRefM2M, which is ambiguous and is not permitted.
275 invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical.
276 invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract.
277 invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract.
278 invalid_models.uniquem2m: ManyToManyFields cannot be unique.  Remove the unique argument on 'unique_people'.
279 """
Note: See TracBrowser for help on using the browser.