My user contact details from front-end not saved in django admin

I am trying to get the Contact information from my "Contact Us" page to my Django admin but its not displaying, I don't find what could be wrong...

my models.py

from django.db import models

class Post(models.Model):
    
    title = models.CharField(max_length=100)
    public_date = models.DateField()
    public_time = models.TimeField()
    image = models.ImageField(upload_to='images/',null=True)
    body = models.TextField()

    class Meta:
        verbose_name = "Post"
        verbose_name_plural = "Posts"
        ordering = ['public_date']

    def summary(self):
        return self.body[:100]

    def pub_date(self):
        return self.public_date.strftime('%b %e,%y')
    # to give layout for time and date

    def __str__(self):
        return self.title

class Contact(models.Model):
    msg_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=70, default="")
    phone = models.CharField(max_length=70, default="")
    desc = models.TextField(max_length=500, default="")
    timeStamp = models.DateTimeField()

    def __str__(self):
        return self.name + '---' + self.email
    # if we write only upto self.name, only name is visible in contact.

forms.py

from django.forms import ModelForm
from .models import Contact


class ContactForm(ModelForm):
    class Meta:
        model = Contact
        fields = '__all__'

views.py

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from blog.models import Post
from .forms import ContactForm
from django.shortcuts import get_object_or_404


def allpost(request):
    post = Post.objects.all()
    #post = [post[i:i + 3] for i in range(0, len(post), 3)]
    return render(request,'posts.html',{'posts':post})


def detail(request,blog_id):
    detail = get_object_or_404(Post, pk = blog_id)
    #return render(request,'/home/deatils',{'post':detail})
    return render(request,'details.html',{'post':detail})

def contact_view(request):
    form = ContactForm()
    if request.method=="POST":

        if form.is_valid():
            name=request.POST.get('name', '')
            email=request.POST.get('email', '')
            phone=request.POST.get('phone', '')
            desc=request.POST.get('desc', '')
            contact = Contact(name=name, email=email, phone=phone, desc=desc)
            contact.save()

            return redirect('success')
    else:
        return render(request, "contact.html", {"form": form})


def successView(request):
    return render(request,"contact_success.html")
    

admin.py

from django.contrib import admin
from blog.models import Post
from .models import Contact

# register admin models here
admin.site.register(Post)
admin.site.register(Contact)

urls.py

from django.urls import path
from blog import views
from django.conf import settings
from django.conf.urls.static import static
from blog.views import successView

urlpatterns = [
    path('',views.allpost,name="allpost"),
    path('search', views.search, name="search"),
    path('contact/', views.contact_view, name="contact"),
    path("success/", successView, name="success_contact"),

    path('<int:blog_id>/',views.detail,name="detail"),
] + static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)

My html code is here.. contact.html

{% extends 'base.html' %}
{% block title %} Contact Us {% endblock %}
{% block content %}
 <div class="container">
     <h3>Contact Us</h3>
     <form action="contact/" method="post">
         {% csrf_token %}
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="Enter Your Name">
  </div>
          <div class="form-group">
    <label for="name">Email</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="Enter Your Email">
  </div>
          <div class="form-group">
    <label for="name">Phome</label>
    <input type="tel" class="form-control" id="phone" name="phone" placeholder="Enter Your Phone Number">
  </div>
          <div class="form-group">
   <div class="form-group">
    <label for="desc">How May We Help You ?</label>
    <textarea class="form-control" id="desc" name="desc" rows="5"></textarea>
    <br>
              <button type="submit" class="btn btn-primary">
                  <a href="/success">Submit</a>
              </button>
 </div>
{%endblock%}

I also mentioned the name of a app in settings.py file. my backend is also working properly but it create a headche. when i press submit button after filling details in contact page, page is navigate to "success/" page but data is not stored/visible in the admin panel.

How can I get rid of that problem?

in views.py

def contact_view(request):
    form = ContactForm() 
    if request.method=="POST":
       form = ContactForm(request.POST) #You should capture data when request is POST
        if form.is_valid():
            name=request.POST.get('name', '')
            email=request.POST.get('email', '')
            phone=request.POST.get('phone', '')
            desc=request.POST.get('desc', '')
            contact = Contact(name=name, email=email, phone=phone, desc=desc)
            contact.save()

            return redirect('success')
    else:
        return render(request, "contact.html", {"form": form})


def successView(request):
    return render(request,"contact_success.html")

First: The reason you're just being redirected lies in the submit button. You defined an action on the form, there is no need to have an anchor tag just redirect to the success page.

         <button type="submit" class="btn btn-primary">
             <span>Submit</span>
         </button>

You can just do:

def contact_view(request):
    form = ContactForm() 
    if request.method=="POST":
       form = ContactForm(request.POST) #You should capture data when request is POST
        if form.is_valid():
            form.save()
            return redirect('success')

        else: #You can leave this away, this is just for simple debugging purposes.
            print(form.errors) # This too.
            print(form.non_field_errors()) # This too.

    return render(request, "contact.html", {"form": form})
  • Since you're using a modelform, there is no need to separately create an instance to save it.
  • You can leave away the else on request.method=='POST', since when the form is invalid, it should redirect to the same form page to display the errors.
  • Else if the form IS valid, it will redirect to 'success'.

As it stands; if your form isn't valid, it will not return ANY response.


The following isn't nescessary if you're planning to use my solution, but some heads up for in the future.

You are using default string values for .get(). Instead of doing:

field=request.POST.get('field', '')

You should do:

field=request.POST.get('field', None)

You can also just use this in your template:

{% for field in form %}
    {{field.label_tag}}
    {{field}}
    {{field.errors}}
{% endfor %}

And then style accordingly inside of the ModelForm

Your template will then look like this:

{% extends 'base.html' %}
{% block title %} Contact Us {% endblock %}
{% block content %}
 <div class="container">
     <h3>Contact Us</h3>
     <form action="contact/" method="post">
         {% csrf_token %}
         {% for field in form %}
             <div class="form-group">
                 {{field.label_tag}}
                 {{field}}
                 {{field.errors}}
             </div>
         {% endfor %}
  
         <button type="submit" class="btn btn-primary">
              <a href="/success">Submit</a>
         </button>
    </form>
 </div>
{%endblock%}

And then add this __init__() method on your form.

def __init__(self, *args, **kwargs):
    super(YourModelForm, self).__init__(*args, **kwargs)
    for field_name, field in self.fields.items():
        if field.widget.attrs.get('class'):
            field.widget.attrs['class'] += ' form-control'
        else:
            field.widget.attrs['class']='form-control'

Have a look at: https://docs.djangoproject.com/en/4.1/topics/forms/modelforms/#django.forms.ModelForm

Back to Top