开发者

Django Multi-Table inheritance and model creation

开发者 https://www.devze.com 2023-01-06 05:15 出处:网络
I have some code that follows the example for multi-table inheritance as given on the documentation page: http://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance. What I am tryi

I have some code that follows the example for multi-table inheritance as given on the documentation page: http://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance. What I am trying to do is create a restaurant around a place.

I've already created a place, and I want to make a restaurant at it like so:

>>> p = Place.objects.get(id=12)
# If p is a Restaurant object, this will give the child class:
>>> p.restaurant
<Restaurant: ...>
>>> r = Restaurant(p)

but I just get this error:开发者_开发百科

TypeError: int() argument must be a string or a number, not 'Place'

I want to add more information to my models, so I don't want to go in and manually set all the fields to be equal. is there anyway to do this?


Unfortunately model "promotion" like this is problematic. The proper way is to create a new Restaurant object by copying the fields from Place. You have to do this by iterating through Place._meta.get_fields_with_model() and seeing which model the fields belong to. I can't give you the exact code for that, but if you can live with GPLed code then it's in transifex.txcommon.models since revision bcd274ce7815.


I think you should add a foreign key to Restaurant like so:

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(models.Model):
    place = models.ForeignKey(Place)
    serves_hot_dogs = models.BooleanField()
    serves_pizza = models.BooleanField()

and then you can do:

>>> p = Place.objects.get(id=12)
>>> r = Restaurant(place=p)


I encountered the same problem. I think I have found a good solution:

I defined my Restaurant model by using three classes like this:

class RestaurantBase(models.Model):
    class Meta:
        abstract = True
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

class Restaurant(Place, RestaurantBase):
    pass

class RestaurantStandalone(RestaurantBase):
    class Meta:
        managed = False
        db_table = Restaurant._meta.db_table
    place_ptr = models.OneToOneRelationship(Place)

Now, if I have a place that I want to upgrade to a restaurant, I do the following:

p = Places.objects.get(id=3)
r = RestaurantStandalone()
r.place_ptr = p
r.save()

now your place is a restaurant

r = Restaurant.objects.filter(place_ptr=p)
print(r.id)
>>3


As I answered my own question here,

I ended up doing something along the lines of

p = Place.objects.get(name="Bob's Cafe")
Restaurant.objects.create(
    place_ptr = p.id,
    serves_hot_dogs = True,
    serves_pizza = False
)
0

精彩评论

暂无评论...
验证码 换一张
取 消