--
Ticket URL: <https://code.djangoproject.com/ticket/16732>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Comment:
But this does work:
{{{
class SlugVersion(models.Model):
class Meta:
abstract = True
unique_together = (('slug', 'version'),)
slug = models.CharField(db_index=True, max_length=10, editable=False)
version = models.IntegerField(db_index=True, editable=False)
class Base(SlugVersion):
name = models.CharField(max_length=10)
class Test(Base):
class Meta:
unique_together = ()
test = models.IntegerField()
}}}
And also creates tables as wanted.
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:1>
Comment (by mitar):
Using such metaclass for `Base` class above solves the problem:
{{{
class ModelBaseFix(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
# We simply remove all unique_together values which we find in a
parent
new_class = super(ModelBaseFix, cls).__new__(cls, name, bases,
attrs)
unique_together = list(new_class._meta.unique_together)
for parent_class in new_class._meta.parents.keys():
for parent_unique_together in
parent_class._meta.unique_together:
try:
unique_together.remove(parent_unique_together)
except ValueError:
pass
new_class._meta.unique_together = tuple(unique_together)
return new_class
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:2>
* stage: Unreviewed => Accepted
Comment:
If I add this code below the models definition in the original report:
{{{
print SlugVersion._meta.abstract, SlugVersion._meta.unique_together
print Base._meta.abstract, Base._meta.unique_together
print Test._meta.abstract, Test._meta.unique_together
}}}
I get:
{{{
% ./manage.py validate
True (('slug', 'version'),)
False (('slug', 'version'),)
False (('slug', 'version'),)
Error: One or more models did not validate:
selftest.test: "unique_together" refers to slug. This is not in the same
model as the unique_together statement.
selftest.test: "unique_together" refers to version. This is not in the
same model as the unique_together statement.
}}}
This shows that `Test` inherits the `Meta` of `Base`, which is wrong,
because `Base` isn't abstract.
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:3>
Comment (by anonymous):
Would this ever be fixed?
I have been avoiding the use of abstract models because of this and it
prevents the model declarations from being DRY...
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:4>
* cc: segfault (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:5>
* cc: direx (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:6>
* status: new => assigned
* owner: nobody => Can Sarıgöl
* has_patch: 0 => 1
* version: 1.3 => master
Comment:
[https://github.com/django/django/pull/11499 PR]
When I read the document about
[https://docs.djangoproject.com/en/2.2/topics/db/models/#meta-inheritance
meta-inheritance], I didn't see the topic that in {{{ abstract = False }}}
case What happens to child meta? as far as I could see from
[https://github.com/django/django/blob/a9179ab032cda80801e7f67ef20db5ee60989f21/django/db/models/base.py#L144
code], {{{ordering}}} and {{{get_latest_by}}} always moving in child meta
in every situation. Should we change the code like my PR + document about
{{{ abstract = False }} and fix the blown up test?
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:7>
* needs_better_patch: 0 => 1
Comment:
Topic for `abstract = False` is not a part of "Abstract base classes"
documentation (see [https://docs.djangoproject.com/en/2.2/topics/db/models
/#meta-and-multi-table-inheritance meta-and-multi-table-inheritance]).
Falling tests show that it is not a proper solution. `('suffix1',
'suffix2')` should be inherited from an abstract class `BookXtra`. I'm
afraid that proposed change is strongly backward incompatible.
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:8>
* needs_better_patch: 1 => 0
Comment:
I got your backward-incompatible concern. I added a case for classes that
have more than one inherited classes and abstract at least one. this can
solve BookXtra test.
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:9>
* needs_tests: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/16732#comment:10>