Django Form with dependent ForeignKey forms on one Page

Viewed 72

Good day, I am trying to implement django with a dependent foreignkey forms on one page. I have three moodels Store, Product, and ProductClothing. They are all ForeignKey related respectively. Users get to create their store seperately, and are redirected to the store detail view where they will now have to upload Products. But this time, I want them to upload both products and product clothing at once. Below is my models.py and views.py of what I have currently on the store detail view. Also the error I get is:

error.py
NOT NULL constraint failed: product_productclothing.product_id
models.py
class Store(models.Model):
    owner = models.ForeignKey(Profile, null=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=100, unique=True)
    slug = AutoSlugField(populate_from='name', unique=True)
    description = models.CharField(max_length=255, blank=True)

    def __str__(self):
        return self.name

class Product(models.Model):
    store = models.ForeignKey(Store, null=True, on_delete=models.SET_NULL)
    owner = models.ForeignKey(Profile, null=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=9, decimal_places=2, verbose_name=_("Regular price"))

class ProductClothing(models.Model):
    CLOTHING_GENDER_CHOICES = (
        ('M', 'Male',),
        ('F', 'Female',),
        ('U', 'Unisex',),
    )
    CLOTHING_TYPE_CHOICES = (
        ('dress', 'Dresses',),
        ('fabric', 'Fabrics',),
        ('shirt', 'Shirts',),
        ('suit', 'Suits',),
        ('tshirt', 'T-Shirts',),
        ('base_layers', 'Base_Layers',),
        ('blazer', 'Blazers',),
    )

    product = models.OneToOneField(Product, on_delete=models.CASCADE)
    gender = models.CharField(max_length=10, choices=CLOTHING_GENDER_CHOICES, blank=True, null=True)
    clothing_type = models.CharField(max_length=255, choices=CLOTHING_TYPE_CHOICES, blank=True, null=True)

    def __str__(self):
        return self.product.title

views.py
@login_required
def store_dashboard_view(request, slug):
    store = get_object_or_404(Store, slug=slug)
    new_product = None
    product_clothing = None
    
    if request.user.profile == store.owner:
        if request.method == 'GET':
            product_form = ProductForm()
            product_clothing_form = ProductClothingForm()
        if request.method == 'POST':
            product_form = ProductForm(data=request.POST)
            product_clothing_form = ProductClothingForm(data=request.POST)
            
            if product_form.is_valid() and product_clothing_form.is_valid():
                new_product = product_form.save(commit=False)
                product_clothing_form.save(commit=False)
                new_product.store = store
                new_product.owner = request.user.profile
                product = product_form.save()
                product = product
                product_clothing_form.product = product
                product_clothing_form.save()
                print(request.user.first_name)
                return redirect('/')
                

        context = {
            "object":store,
            "form": product_form,
            "product_clothing_form": product_clothing_form
        }
        return render(request, "store/store-dashboard.html", context)
    else:
        return redirect('store:store-detail-view', slug=store.slug)



1 Answers

Try to Change this part

        if product_form.is_valid() and product_clothing_form.is_valid():
            new_product = product_form.save(commit=False)
            product_clothing_form.save(commit=False)
            new_product.store = store
            new_product.owner = request.user.profile
            product = product_form.save()
            product = product
            product_clothing_form.product = product
            product_clothing_form.save()
            print(request.user.first_name)
            return redirect('/')

to

        if product_form.is_valid() and product_clothing_form.is_valid():
            new_product = product_form.save(commit=False)
            product_clothing_form = product_clothing_form.save(commit=False)
            new_product.store = store
            new_product.owner = request.user.profile
            new_product.save() #this is correct your mistake was here
            print(new_product)
            product_clothing_form.product = new_product
            product_clothing_form.save()
            print(request.user.first_name)
            return redirect('/')
Related