简体   繁体   中英

django, how to deal with modelForm with foreignkey?

I want to deal with foreignKey with a modelForm and it raise this error:

ValueError at /3/
  The view main.views.ProductDetailView didn't return an
  HttpResponse object. It returned None instead.

the problem is on the Wilaya and commune fields, because when i remove them all works fine.

in views.py

class ProductDetailView(ModelFormMixin, DetailView):
    model = Produit
    context_object_name = 'produit'
    form_class = CheckoutCreateForm

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context["form"] = self.get_form()
        context["wilayas"]= Wilaya.objects.all()
        context["communes"]= Commune.objects.all()
        return context

    def post(self, request, *args, **kwargs):
        # self.object = self.get_object()
        # form = self.get_form()
        form = CheckoutCreateForm(request.POST)
        if form.is_valid():
            checkout = form.save(commit=False)
            checkout.produit = self.get_object()
            checkout.prix = self.get_object().price
            checkout.save()
            wilaya = form.cleaned_data['wilaya']
            commune = form.cleaned_data['commune']
            quantity = form.cleaned_data['quantity']
            nom_du_client = form.cleaned_data['nom_du_client']
            prenom_du_client = form.cleaned_data['prenom_du_client']
            adresse_du_client = form.cleaned_data['adresse_du_client']
            print('jusque la cv')
            try:
                form = CheckoutCreateForm()
                return redirect(f'/{self.get_object().pk}')
            except:
                return redirect('/')

in models.py

class Wilaya(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class Commune(models.Model):
    Wilaya = models.ForeignKey(Wilaya, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class Checkout(models.Model):
    produit = models.ForeignKey('Produit', on_delete=models.CASCADE)
    prix = models.IntegerField(default=0)
    nom_du_client = models.CharField(max_length=40)
    prenom_du_client = models.CharField(max_length=40)
    adresse_du_client = models.CharField(max_length=40)
    date_added = models.DateTimeField(auto_now_add=True)
    wilaya = models.ForeignKey(Wilaya, on_delete=models.SET_NULL, null=True, blank=True)
    commune = models.ForeignKey(Commune, on_delete=models.SET_NULL, null=True, blank=True)
    quantity = models.PositiveIntegerField(default=1)
    confirmer = models.BooleanField(default=False)

    def __str__(self):
        return str(self.produit)

in forms.py

from django import forms 
from .models import Checkout, Commune , Wilaya
class CheckoutCreateForm(forms.ModelForm):
    class Meta:
        model = Checkout 
        fields = ['nom_du_client', 'prenom_du_client','adresse_du_client', 'quantity', 'wilaya', 'commune']

in html file:

  <form class="card-body" method='POST' id="checkoutForm" >
                  {% csrf_token %}
                  <!--Grid row-->
                  <div class="row">

                    <!--Grid column-->
                    <div class="col-md-6 mb-2">

                      <!--firstName-->
                      <div class="md-form ">
                        <input type="text" name="nom_du_client" id="firstName" class="form-control">
                        <label for="nom_du_client" class="">First name</label>
                      </div>
  .... rest of the form 

    <button class="btn btn-primary btn-lg btn-block" type="submit">Continue to checkout</button>

                </form>

The error is pretty self-explanatory:

The view main.views.ProductDetailView didn't return an HttpResponse object. It returned None instead.

If you look at the reduced version of your code:

class ProductDetailView(ModelFormMixin, DetailView):
    def post(self, request, *args, **kwargs):
        ...

        if form.is_valid():
            ...
            try:
                ...
                return redirect(f'/{self.get_object().pk}')
            except:
                return redirect('/')

You can notice that the method post() returns None if the form is not valid.

One possible solution is to have a return redirect(...) at the end as well:

class ProductDetailView(ModelFormMixin, DetailView):
    def post(self, request, *args, **kwargs):
        ...

        if form.is_valid():
            ...
            try:
                ...
                return redirect(f'/{self.get_object().pk}')
            except:
                pass

        return redirect('/')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM