Hello all,
I was wonder if there is a way to turn a model instance into an
instance of a subclass of it's class. E.g.:
class Document(models.Model):
doctype = models.CharField(max_length=256, blank=True, null=True)
class UploadedFile(Document):
filename = models.CharField(max_length=256)
Given a Document that isn't already an UploadedFile, can I turn it
into one? I know at the database level it's just a matter of inserting
a new row into the uploadedfile table with document_ptr_id = the
Document's id. I've tried
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>
Um, I'm not sure what it is you're trying to demonstrate here... in myOn Mon, Dec 20, 2010 at 4:49 PM, Marc Aymerich <glic...@gmail.com> wrote:
>
>
> On Mon, Dec 20, 2010 at 8:29 PM, morgan wahl <morgy...@gmail.com> wrote:
>>
>> Hello all,
>>
>> I was wonder if there is a way to turn a model instance into an
>> instance of a subclass of it's class. E.g.:
>>
>> class Document(models.Model):
>> doctype = models.CharField(max_length=256, blank=True, null=True)
>>
>> class UploadedFile(Document):
>> filename = models.CharField(max_length=256)
>>
>> Given a Document that isn't already an UploadedFile, can I turn it
>> into one? I know at the database level it's just a matter of inserting
>> a new row into the uploadedfile table with document_ptr_id = the
>> Document's id. I've tried
>>
>
> I think that something like this should do the work:
> Document.UploadFile.filename="rat.doc"
> Document.save()
>
> --
> Marc
example bits of code Document and UploadedFile are Model classes, not
instances.
Yes, I had hope that would work, but it doesn't (see my original post). In your example u.doctype would end up as None instead of 'whatever'.
On 20 December 2010 23:14, morgan wahl <morgy...@gmail.com> wrote:
> Yes, I had hope that would work, but it doesn't (see my original post). In
> your example u.doctype would end up as None instead of 'whatever'.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>
--
Łukasz Rekucki
I'm not sure how InheritanceManager would quite solve _this_ problem,
although it certainly is handy (I've independently implemented
something like InheritanceCastModel already). So, thanks for the tip!
Just to clarify:
My problem is that Document instances get created at some point (and
referenced by other models), and at some later date a Document might
need to be transmuted to a UploadedFile (which should be fine
hypothetically).
The actual classes I'm dealing with are a little more complicated, my
example was just for this question.
-Morgan
My situation is that I have various instances of Document, some of
which are also instances of UploadedFile (or other Document
subclasses). I would like to turn ones which _aren't_ already
UploadedFile instances into ones that are, without changing their
existing fields (especially their IDs). I'm not trying to break the
one-to-one relationship between the tables in multi-table inheritance.
2010/12/20 Łukasz Rekucki <lrek...@gmail.com>:
Sent from my mobile device
2010/12/20 Łukasz Rekucki <lrek...@gmail.com>:
It is a duplicate, that's why I mentioned #7623 which is tracking this
bug. Existence of another table is irrelevant here, IMHO. The main
scheme is the same: You have an instance of class A and you want to
create an instance of class B which is a subclass of A, by writing:
a = A.object.get(pk=1) # existing instance of A
b = B(parent=A)
b.save() # this will fail
The patch on #7623 is describing exactly this situation, so you should
check it out.
Marc Aymerich writes:
> [...]
>
> Morgan, take a look at the inheritanceManager of this app:
> https://github.com/carljm/django-model-utils#readme
Is anything like this planned for core Django? It's the third or
forth time I see someone needing it.
Tsch�,
Torsten.
--
Torsten Bronger, aquisgrana, europa vetus
Jabber ID: torsten...@jabber.rwth-aachen.de
or http://bronger-jmp.appspot.com
It's not planned for 1.3. Whether it is planned for 1.4 will depend
entirely on whether someone drives the issue.
For the record, the use case you describe was considered at the time
model inheritance was introduced. If you search the archives for
"CORBA narrowing" you should be able to find the thread where Malcolm
and I discussed it.
At the time, we decided to omit support for 'narrowing' (to use the
CORBA parlance) as part of the default feature set because it requires
either:
a) table overhead to store the type of the child instance
b) an expensive query (or list of queries) that isn't obviously expensive.
We weren't (and I'm still not) willing to impose either of these
overheads by default.
The good news is that either strategy is easy to implement without
modifications to core. I've got several classes in production that do
narrowing-like behavior (for the record, both using strategy (a)).
With a bit of extra effort, this should be easy to turn into a mixin
that could be shared as part of a third-party support library, much as
django-treebeard or django-mptt provide model support extensions
implementing tree-like structures.
Yours,
Russ Magee %-)
Russell Keith-Magee writes:
> On Tue, Dec 21, 2010 at 8:33 PM, Torsten Bronger
> <bro...@physik.rwth-aachen.de> wrote:
>> Hall�chen!
>>
>> Marc Aymerich writes:
>>
>>> [...]
>>>
>>> Morgan, take a look at the inheritanceManager of this app:
>>> https://github.com/carljm/django-model-utils#readme
>>
>> Is anything like this planned for core Django? �It's the third or
>> forth time I see someone needing it.
>
> [...]
>
> At the time, we decided to omit support for 'narrowing' (to use
> the CORBA parlance) as part of the default feature set because it
> requires either:
>
> a) table overhead to store the type of the child instance
> b) an expensive query (or list of queries) that isn't obviously expensive.
>
> We weren't (and I'm still not) willing to impose either of these
> overheads by default.
I must clarify my use of "core Django" above. Of course this may
well be realised in contrib/ as an optional feature. However, I'd
love to see it in the Django release with explanations in the Django
docs.
> The good news is that either strategy is easy to implement without
> modifications to core. I've got several classes in production that do
> narrowing-like behavior (for the record, both using strategy (a)).
(a) is the way to go in my opinion. I think the table overhead
itself is not so much of a problem but any migration of old
databases necessary due to it. So, I understand that it cannot be
default behaviour.
> With a bit of extra effort, this should be easy to turn into a mixin
> that could be shared as part of a third-party support library, much as
> django-treebeard or django-mptt provide model support extensions
> implementing tree-like structures.
As somebody who has strugged with this problem for a along time and
having seen a couple of solutions along the road, I find
https://github.com/carljm/django-model-utils quite appealing and
finished.
#7623's description is something a bit more broad. In terms of your
example, if C is also a subclass of A and b an instance of B, it's
proposing
c = C(parent=b)
presumably the resulting 'c' instance would have all the fields of A
and C and it would share it's A and fields with the 'b' instance. Thus
if A has a string field called 'name' and you do:
c.name = 'someting a rather'
It would effectively set b.name as well (since they would both be
backed by the same row in the table corresponding to A). This is not
how class inheritance typically behaves, and I think it breaks the
analogy Django's ORM makes between it's tables in the database and
Python objects. (Now that I think about my example may have as well,
just a bit more subtly.)