首页 > 解决方案 > Django 中的链式下拉菜单未将数据存储到数据库(Postgresql)

问题描述

我正在尝试在 Django 中创建一个链式下拉菜单,该下拉菜单用于选择国家/地区,只有属于该国家/地区的那些州才能进入下拉列表中进行选择。我已使用 J-Query 进行下拉,并且工作正常。但是在从表单发送数据后,表单数据将进入控制台,因为我已将表单值打印到控制台以便更好地理解,但没有将数据保存到数据库中,即使数据正确,form.is_valid 也会给出 False。

为什么即使表单数据正确,它也不存储到数据库中

模型.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser,AbstractUser

class Country_Model(models.Model):
    country = models.CharField(max_length=50)
    def __str__(self):
        return self.country

class State(models.Model):
    country = models.ForeignKey(Country_Model,on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    def __str__(self):
        return self.name



class StudentsRegistrationModel(AbstractUser):
    GENDER = (('F', 'Female',),('M', 'Male',),('O', 'Other',))
    email = models.EmailField(unique=True)
    fathers_name = models.CharField(max_length=25)
    gender = models.CharField(max_length=1,choices=GENDER,default=None)
    address = models.CharField(max_length=50)
    country = models.ForeignKey(Country_Model,on_delete=models.CASCADE)
    state = models.ForeignKey(State,on_delete=models.CASCADE)
    phone_number = models.CharField(verbose_name="Phone Number",max_length=10)
    last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS=[]

表格.py

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from app1.models import StudentsRegistrationModel,State

class Students_Registration_Form(UserCreationForm):
    class Meta:
        model = get_user_model()
        fields = ('first_name','last_name','gender','address','country','state','phone_number','email','password1','password2')
    def __init__(self,*args,**kwargs):
        super(Students_Registration_Form,self).__init__(*args,**kwargs)
        self.fields['country'].empty_label = 'Select'
        self.fields['state'].empty_label = 'Select'
        self.fields['state'].queryset = State.objects.none()

网址.py

from django.urls import path
from app1 import views

urlpatterns = [
    path('home/',views.home,name='home'),
    path('add/',views.insert_student_details,name='add-student'),
    path('ajax/load-cities/',views.load_cities, name='ajax_load_cities'),

]

    

视图.py

from django.shortcuts import render, redirect 
from  django.contrib import messages 
from django.contrib.auth import get_user_model
from app1.models import StudentsRegistrationModel,Country_Model,State
from app1.form import Students_Registration_Form
def home(request):
    return render(request,'app1/home.html')

def insert_student_details(request):
    if request.method =='POST':
        form = Students_Registration_Form(request.POST)
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        gender = request.POST.get('gender')
        address = request.POST.get('address')
        country = request.POST.get('country')
        state = request.POST.get('state')
        phone_number = request.POST.get('phone_number')
        email = request.POST.get('email')
        password = request.POST.get('password')
        password1 = request.POST.get('password1')
        print(first_name)
        print(last_name)
        print(gender)
        print(address)
        print(country)
        print(state)
        print(phone_number)
        print(email)
        print(password)
        print(password1)

        print(form.is_valid())
        if form.is_valid():
            form.save()
            print('Record Inserted Successfully')
            messages.success(request,"Thanks for successfull Registration")
            return redirect('/')
        else:
            print('Not stored')
    else:
        form = Students_Registration_Form()

    return render (request,'app1/info.html',{'form':form})


def load_cities(request):
    country_id = request.GET.get('country')
    cities = State.objects.filter(country_id=country_id).order_by('name')
    return render(request, 'app1/city_dropdown_list_options.html', {'cities': cities}) 

base.html

 <html>
    <head>
    </head>
    <body>
    <h1>
    Welcome to Recruitment Site
    </h1>
    {% block content %}
    {% endblock %}
    </body>
    </html>

city_dropdown_list_options.html

<option value="">Select</option>
{% for city in cities %}
<option value="{{ city.pk }}">{{ city.name }}</option>
{% endfor %}

主页.html

     {% extends 'app1/base.html' %}
        {% block content %}
        
        <p>
        I am home page
        </p>
        {% endblock content %}
        

信息.html

 {% extends 'app1/base.html' %}
    {% block content %}
    <p>I am  Info Page</p>
      <form action="" method="post" id="personForm" data-cities-url="{% url 'ajax_load_cities' %}" novalidate>
            {% csrf_token %}
            <table>
              {{ form.as_table }}
             </table>
            <button type="submit">Register</button>
          </form>
          <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
          
          <script>
            $("#id_country").change(function () {
              var url = $("#personForm").attr("data-cities-url");  // get the url of the `load_cities` view
              var countryId = $(this).val();  // get the selected country ID from the HTML input
          
              $.ajax({                       // initialize an AJAX request
                url: url,                    // set the url of the request (= localhost:8000/add/ajax/load-cities/)
                data: {
                  'country': countryId       // add the country id to the GET parameters
                },
                success: function (data) {   // `data` is the return of the `load_cities` view function
                  $("#id_state").html(data);  // replace the contents of the city input with the data that came from the server
                }
              });
          
            });
          
    
            
          </script>
    {% endblock %}

控制台输出:

System check identified no issues (0 silenced).
April 01, 2021 - 10:35:03
Django version 2.2, using settings 'custom_pro.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[01/Apr/2021 10:35:19] "GET /ajax/load-cities/?country=230 HTTP/1.1" 200 4815
[01/Apr/2021 10:35:22] "GET /ajax/load-cities/?country=231 HTTP/1.1" 200 2460
harsh
singh
M
Dallas
231
3970
8547896654
h@gmail.com
asdf@1234
False
Not stored
[01/Apr/2021 10:35:36] "POST /add/ HTTP/1.1" 200 13714

标签: pythonjquerydjangodjango-modelsdjango-views

解决方案


在您的表单__init__方法中,您编写:

self.fields['state'].queryset = State.objects.none()

最初这很好,但字段查询集也用于验证用户选择的选择是否正确。所以这导致在这种情况下没有选择是有效的。您应该处理country已选择或表单只是更新实例的情况:

class Students_Registration_Form(UserCreationForm):
    class Meta:
        model = get_user_model()
        fields = ('first_name','last_name','gender','address','country','state','phone_number','email','password1','password2')
    
    def __init__(self,*args,**kwargs):
        super(Students_Registration_Form,self).__init__(*args,**kwargs)
        self.fields['country'].empty_label = 'Select'
        self.fields['state'].empty_label = 'Select'
        self.fields['state'].queryset = State.objects.none()
        if self.instance.pk:
            # If updating an instance
            self.fields['state'].queryset = self.instance.country.state_set.order_by('name')
        if 'country' in self.data:
            # If this is a submitted form
            try:
                country_id = int(self.data.get('country'))
                self.fields['state'].queryset = State.objects.filter(country_id=country_id).order_by('name')
            except (ValueError, TypeError):
                pass

推荐阅读