Question

I have the following form:

class PlaceForm(forms.ModelForm):

class Meta:        
    model = Place

I have the following models:

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

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

In my view I want to conditionally save either a Place or a Restaurant depending on the incoming url.

I have tried the following:

if form.is_valid():
                place = form.save(commit=False)
                place.customer = customer
                place.save()

                if url_name == 'restaurant':
                     restaurant = Restaurant(place_ptr_id=place.id)
                     restaurant.save()

This creates a place from the form and then tries to create a restaurant, but fails with following: (1048, "Column 'customer_id' cannot be null")

This is telling me that a new row for a new place is trying to be inserted and then the restaurant row.

I see a few different options:

  1. Convert the Place to a restaurant and save the additional to the converted object.
  2. Conditionally change the model type of the form to either Place or Restaurant

How can I accomplish saving the different parent and child objects conditionally?

Was it helpful?

Solution

It is related to Django model inheritance: create sub-instance of existing instance (downcast)? which suggests how to add object with existing base class object.

You may want to look at my question: Derived model filefield not available


In nutshell what you have to do is

restaurant = Restaurant(place_ptr_id=place.id)
restaurant.__dict__.update(place.__dict__)
restaurant.save()

OTHER TIPS

You can add null=True and blank=True.

models:

class Place(models.Model):
    customer = models.ForeignKey(Customer, null=True, blank=True)
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top