简体   繁体   中英

Django save() is not saving form to database

Hello I have problem with saving forms to database. When I try to save the AdHistoryForm in ads_history_add view the forim is rendered correctly but after submitting nothing happens aside of redirecting me to ads_history_list view.

In addition when I try to submit this form with empty field it doesnt show any errors (I included them in template), so maybe it is validation thing.

When I try to add Ad in ads_add view everything is ok.

Can you help me?

models.py

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User


class Ad(models.Model):
    title = models.CharField(max_length=128, verbose_name=_("name"), help_text=_("required"), unique=True)
    content = models.TextField(verbose_name=_("content"), blank=True)
    url = models.URLField(verbose_name=_("website"), blank=True)
    date_create = models.DateTimeField(auto_now_add=True)
    date_modify = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.title


class AdHistory(models.Model):
    ad = models.ForeignKey(Ad)
    user = models.ForeignKey(User)
    comment = models.TextField(verbose_name=_("comment"), help_text=_("required"))
    date_create = models.DateTimeField(auto_now_add=True)
    date_modify = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.comment

forms.py

from django import forms

from .models import Ad, AdHistory


class AdForm(forms.ModelForm):
    class Meta:
        model = Ad
        fields = ['title', 'content', 'url']


class AdHistoryForm(forms.ModelForm): 
    class Meta:
        model = AdHistory
        fields = ['comment']

views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
from django.utils.translation import ugettext as _

from .models import Ad, AdHistory
from .forms import AdForm, AdHistoryForm   



@login_required
@user_passes_test(lambda u: u.is_superuser)
def ads_list(request):
    ads_list = Ad.objects.all().order_by('-date_modify')
    context = {'list': ads_list}
    return render(request, 'ads_list.html', context)

@login_required
@user_passes_test(lambda u: u.is_superuser)
def ads_add(request):
    form = AdForm(request.POST or None)
    if form.is_valid():
        form.save()
        return redirect('ads_list')
    context = {'form': form}
    return render(request, 'ads_form_add.html', context)

@login_required
@user_passes_test(lambda u: u.is_superuser)
def ads_history_list(request, ad_id):
    ad = get_object_or_404(Ad, pk=ad_id)
    history_list = AdHistory.objects.select_related().filter(ad=ad).order_by('-id')
    context = {'list': history_list, 'object': ad}
    return render(request, 'ads_history_list.html', context)

@login_required
@user_passes_test(lambda u: u.is_superuser)
def ads_history_add(request, ad_id):
    ad = get_object_or_404(Ad, pk=ad_id)
    f = AdHistoryForm(request.POST or None)
    if f.is_valid():
        new_entry = f.save(commit=False)
        new_entry.ad = ad
        new_entry.user = request.user
        new_entry.save()
        return redirect('ads_history_list', ad_id)
    context = {'form': f, 'object': ad}
    return render(request, 'ads_history_add.html', context)

urls.py

rom django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required

from ads import views

urlpatterns = patterns(
    '',
    url(r'^$', views.ads_list, name="ads_list"),
    url(r'^add/', views.ads_add, name="ads_add"),
    url(r'^(?P<ad_id>\d+)/history/$', views.ads_history_list, name="ads_history_list"),
    url(r'^(?P<ad_id>\d+)/history/add$', views.ads_history_add, name="ads_history_add"),
)

both form templates inherits from this template:

<form role="form" method="post" action=".">

    {% csrf_token %} 

    <table class="table table-bordered crm-form">

        {% for field in form.visible_fields %} 

        <tr>
            <th>
                {{ field.label }}
            </th>
            <td>
                {{ field }}

                <small>{{ field.help_text }}</small>

                {% if field.errors %}
                <div class="alert alert-danger" role="alert">{{ field.errors }}</div>
                {% endif %}

            </td>

        </tr>

        {% endfor %}
    </table>

     <button type="submit" name="submit" class="btn btn-success crm-float-right">
        {% trans 'Save' %}
    </button>

</form>

The POST request never reaches your ads_history_add view because your ads_history_add URL pattern does not have a trailing slash. Without the trailing slash, action="." in the ads_form_add.html template results in a POST to (?P<ad_id>\\d+)/history/

Add the trailing slash and everything should work as expected. Alternatively, you could omit the action attribute to tell the browser to POST to the current URL.

Also note that, although not relevant here, it is probably a good habit to display {{ form.non_field_errors }} .

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