In Django How to set up dependent dropdown lists - django

I am attempting to set up dependent dropdown lists in a Django 3.1 site. The lists are populated via another app (Django-Machina) DB tables. I attempted to adapt the example here. However I am new to Django and Python and so far, I am not able to get this to work.
My files are as follows:
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from machina.core.db.models import get_model
from django.db.models import Q
Forum = get_model("forum", "Forum")
class CustomUser(AbstractUser):
age = models.PositiveIntegerField(null=True, blank=True)
business_location_state = models.ForeignKey(Forum, null=True, on_delete=models.SET_NULL, limit_choices_to={"lft":1})
business_location_county = models.ForeignKey(Forum, null=True, on_delete=models.SET_NULL, related_name='county', limit_choices_to=(~Q(lft__in = (1,2))))
views.py
from django.urls import reverse_lazy
from django.views.generic import CreateView
from .forms import CustomUserCreationForm
from .models import CustomUser
from django.shortcuts import render
from machina.core.db.models import get_model
from django.db.models import Q
Forum = get_model("forum", "Forum")
class SignUpView(CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
def load_counties(request):
parent_id = request.GET.get('business_location_state')
counties = Forum.objects.filter(parent_id=parent_id).order_by('name')
return render(request, 'hr/county_dropdown_list_options.html', {'counties': counties})
accounts/urls.py
# accounts/urls.py
from django.urls import path
from .views import SignUpView
from . import views
urlpatterns = [
path('signup/', SignUpView.as_view(), name='signup'),
path('ajax/load-counties/', views.load_counties, name='ajax_load_counties'), # ajax to load counties
]
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('username', 'email', 'age', 'business_location_state', 'business_location_county')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['business_location_county'].queryset = CustomUser.objects.none()
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'age','business_location_state', 'business_location_county')
count_dropdown_list_options.html
<!-- templates/hr/county_dropdown_list_options.html -->
<option value="">---------</option>
{% for county in counties %}
<option value="{{ business_location_county.pk }}">{{ business_location_county.name }}</option>
{% endfor %}
signup.html
<!-- templates/registration/signup.html -->
{% extends 'base.html' %}
{% block title %}
Sign Up
{% endblock title %}
{% block content %}
<h2>Sign up</h2>
<form method="post" id=signupForm data-counties-url="{% url 'ajax_load_counties' %}" novalidate>
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign Up</button>
</form>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$("#id_business_location_state").change(function () {
var url = $("#signupForm").attr("data-counties-url"); // get the url of the `load_cities` view
var stateId = $(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/hr/ajax/load-cities/)
data: {
'business_location_state': stateId // add the state id to the GET parameters
},
success: function (data) { // `data` is the return of the `load_cities` view function
$("#id_county").html(data); // replace the contents of the city input with the data that came from the server
}
});
});
</script>
{% endblock content %}
I am not currently seeing any errors but the counties list is not changing based on the "Business location state" choice. Any ideas about what is going wrong?

Related

In Django how to populate a form dropdown list form a column in a database

I am new to Django and python. I am attempting to populate a field in a custom user creation form with values in a separate table/column the database. Those values are created via another app and model (the Django Machina forum app).
So far I have not been able to figure out how to even import the model to gain access to the values.
My models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
age = models.PositiveIntegerField(null=True, blank=True)
business_location_state = models.CharField(max_length=100)
views.py
from django.urls import reverse_lazy
from django.views.generic import CreateView
from .forms import CustomUserCreationForm
class SignUpView(CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('username', 'email', 'age', 'business_location_state')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'age',)
signup.html
{% extends 'base.html' %}
{% block title %}
Sign Up
{% endblock title %}
{% block content %}
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign Up</button>
</form>
{% endblock content %}
The Machina github is found here: https://github.com/ellmetha/django-machina
Any ideas about how to use values in the table forum_forum and column "id" as a dropdown in the field business_location_state
It looks like you want to use a foreign key pointing out to the Forum table in Machina.
If that is the case, then you should define the business_location_state field as a models.ForeignKey.
This ForeignKey should be pointing out to the Forum model. If you look at Machina source code you can see how they access this model and replicate it.
from machina.core.db.models import get_model
Forum = get_model("forum", "Forum")
class CustomUser(AbstractUser):
age = models.PositiveIntegerField(null=True, blank=True)
business_location_state = models.ForeignKey(Forum, on_delete=models.SET_NULL)

Django 1.10 Form Fields Using Foundation 6 Not Showing In Template

I am trying to build a simple landing page in Django that will allow users to sign up for an email newsletter. I am using this cookie cutter template - https://github.com/Parbhat/cookiecutter-django-foundation - because it integrates Foundation 6 from the jump.
The challenge is that the form fields are not showing in the template. Any help would be appreciated.
My models.py is:
class Subscribe(models.Model):
email = models.EmailField()
subscription_status = models.BooleanField(default=True)
create_date = models.DateTimeField(auto_now_add = True, auto_now = False)
update_date = models.DateTimeField(auto_now_add = False, auto_now = True)
def __unicode__(self):
return self.email
My forms.py is:
from django import forms
from .models import Subscribe
class SubscribeForm(forms.ModelForm):
class Meta:
model = Subscribe
fields = ('email',)
My views.py is:
from django.shortcuts import render
from subscribers.forms import EmailForm, SubscribeForm
from .models import Subscribe
def home(request):
form = SubscribeForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
#we might need to do something here.
email = form.cleaned_data['email']
new_join_old, created = Subscribe.objects.get_or_create(email=email)
#new_join.save()
context = {"form": form}
template = "pages/home.html"
return render(request, template, context)
And my template is:
{% extends "base.html" %}
{% load foundation_formtags %}
{% block content %}
<section class="hero">
<!-- HERO SECTION -->
<div class="homebox">
<div class="wrap">
<p>Lorem Ipsum</p>
<form class="form" method="post" action=""> {% csrf_token %}
{{ form|as_foundation }}
<input type='submit' value='Subscribe' class='btn' />
</form>
</div>
</div>
</section>
My urls.py is:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from django.conf.urls import url
from . import views
from subscribes.views import home
urlpatterns = [
url(r'^$', home, name='home'),
]
Thanks!

Flask Mongoengine validation error with wtfform

I've been working on WTF form with flask and mongoengine. When I try to register on html side as a new user this debug message appears.
ValidationError: ValidationError (User:None) (Field is required: ['password'] cannot parse date "asd": ['created_at'])
I've basic django background. I am new to flask and I don't know how to figure it out.
Model:
import datetime
from copylighter import db, app
from slugify import slugify
from flask_login import UserMixin
class User(db.Document, UserMixin):
created_at = db.DateTimeField(default=datetime.datetime.now)
name = db.StringField(max_length=30, required=True, unique=True, help_text="Your helptext here")
email = db.StringField(max_length=100, required=True, unique=True, help_text="Your helptext here")
active = db.BooleanField()
password = db.StringField(max_length=255, required=True, help_text="Your helptext here")
slug = db.StringField(help_text="Your helptext here")
roles = db.ListField(db.ReferenceField('Role'))
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
return super(User, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
forms.py
from flask_wtf import Form
from wtforms.fields import StringField, PasswordField, BooleanField, SubmitField, HiddenField
from wtforms import validators
from models import User
import datetime
class SignUpForm(Form):
created_at = HiddenField()
name = StringField(u'Username', [validators.Required()])
email = StringField(u'Email', [validators.Required()])
password = PasswordField(u'Password', [validators.Required()])
submit = SubmitField('Sign Up')
class Meta():
__model__ = 'User'
views.py
from flask import Flask, render_template, redirect, url_for, request, flash
from flask_login import login_required, login_user
from copylighter import db, app, login_manager
import datetime
from forms import LoginForm,SignUpForm
from slugify import slugify
from flask_login import UserMixin
from models import User
#app.route("/register", methods=['GET','POST'])
def register():
formS = SignUpForm()
#if formS.validate_on_submit():
#name = formS.name.data
#email = formS.email.data
#password = formS.password.data
if request.method == 'POST':
formS = SignUpForm()
formS.created_at.data = datetime.datetime.now()
if formS.validate() == False:
return render_template('register.html', form=formS)
if formS.validate_on_submit():
newuser = User(formS.name.data, formS.email.data, formS.password.data)
newuser.save()
return redirect(url_for('profile'))
return render_template("register.html", form=formS)
and finally
register.html
{% extends "base.html" %}
{% block content %}
<div class="container">
<form action="" method="post">
{{form.hidden_tag()}}
{{form.name.label}}
{{form.name}}
{% if form.name.errors %}
<span class="text-danger">Error</span>
{% endif %}
{{form.email.label}}
{{form.email}}
{% if form.email.errors %}
<span class="text-danger">Error</span>
{% endif %}
{{form.password.label}}
{{form.password}}
{% if form.password.errors %}
<span class="text-danger">Error</span>
{% endif %}
{{ form.submit }}
</form>
</div>
{% endblock content %}
any help will be appreciated...
The problem was based on views.py
if formS.validate_on_submit():
newuser = User(formS.name.data, formS.email.data, formS.password.data)
newuser.save()
save() function doesn't know where to insert form.blahblah.data. I added required model variables into newuser object and matched to values those came from the html form
Here is the right sample:
newuser = User(name=formS.name.data, email=formS.email.data, password=formS.password.data, created_at=datetime.datetime.now())

HttpResponseRedirect doesn't work after new_join.save()

I tried to make simple request form. And I need to redirect user to "thank you" page after successful form sent. But after user hit "send" button - nothing happens. Just reload form page without form cleaning also.
Form is on "call" page, redirect needs "confirm" page...
So, task is: user fill the form on page "call" and after hitting "send" button, goes to "confirm" page.
My model:
# -*- coding: utf-8 -*-
from django.db import models
from django.forms import ModelForm
# Create your models here.
class Join(models.Model):
class Meta():
db_table = 'expert_request'
user_expert = models.CharField(max_length=100)
user_name = models.CharField(max_length=100)
user_cost = models.CharField(max_length=100)
user_email = models.EmailField()
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self):
return self.user_email
my "forms.py":
from django import forms
from userform.models import Join
class JoinForm(forms.ModelForm):
class Meta:
model = Join
This is my "views.py":
from django.shortcuts import render
from django.shortcuts import HttpResponseRedirect, Http404
# Create your views here.
from userform.forms import JoinForm
from userform.models import Join
def userform(request):
form = JoinForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
new_join.save()
HttpResponseRedirect('/confirm/')
context = {"form": form}
template = "userform.html"
return render(request, template, context)
def confirm(request):
return render(request, 'confirm.html')
This is my URL's:
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
(r'^tinymce/', include('tinymce.urls')),
url(r'^$', 'expert.views.index', name='index'),
url(r'^(\d+)/?$', 'expert.views.index'),
url(r'^call/$', 'userform.views.userform', name='call'),
url(r'^confirm/$', 'userform.views.confirm', name='confirm'),
)
My template "userform.html":
{% load staticfiles %}
<form style="position:relative" method="POST" action="">{% csrf_token %}
{{ form.user_expert }}
<p style="position:absolute; top:50px; left:20px; color:#FF0000;">{{ form.user_expert.errors.as_text }}</p>
{{ form.user_name }}
<p style="position:absolute; top:182px; left:20px; color:#FF0000;">{{ form.user_name.errors.as_text }}</p>
{{ form.user_cost }}
<p style="position:absolute; top:50px; left:380px; color:#FF0000;">{{ form.user_cost.errors.as_text }}</p>
{{ form.user_email }}
<p style="position:absolute; top:182px; left:380px; color:#FF0000;">{{ form.user_email.errors.as_text }}</p>
<button type="submit">Send</button>
<div class="clear"></div>
</form>
Maybe you forgot the return statement in userform view function? Fix its beginning like this:
def userform(request):
form = JoinForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
new_join.save()
return HttpResponseRedirect('/confirm/')

Django Modelform: cannot import name

#### model using ModelForm: models.py
from django.db import models
from django.forms import ModelForm
class customers(models.Model):
name = models.CharField(max_length=50)
custAdd = models.TextField()
class Meta:
db_table = 'tb_amit_test'
ordering = ['-name']
verbose_name_plural = 'customers'
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('customers_customers', (), { 'customers_name': self.name })
class customerForm(ModelForm):
class Meta:
model=customers
#### View:views.py
from django.shortcuts import render_to_response
from mtcc_customer_db import customers
from mtcc_customer_db import customerForm
from django.template import RequestContext
def adddata(request):
if request.method == 'POST':
f=custform(request.POST)
if f.is_valid():
newcust=f.save(commit=False)
newcust.save()
return HttpResponseRedirect('/')
return render_to_response('index.html',
context_instance=RequestContext(request))
#### URLs:
from django.conf.urls import patterns, include, url
from mtcc_customer_db import settings
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),)
urlpatterns +=patterns('mtcc_customer_db.customers.views',
(r'^customers/$', 'adddata'),)
### Template: customer.html
{% extends "base.html" %}
{% block site_wrapper %}
<div id="main">
{% include "tags/navigation.html" %}
Skip to main content
<form action="." method="post">
<input type="text" name="name" id="name" value="{{name}}">
<input type="text" name="custAdd" id="custAdd" value="{{custAdd}}">
<input type="submit" value="Submit">
</form>.........
{% endblock %}
I am getting the error in the browser:
Request Method: GET
Request URL: someaddress.customers/
Django Version: 1.4.3
Exception Type: ImportError
Exception Value:
--->>cannot import name customerForm
Where am i going wrong?? Please help
Try this:
from your_module_name.models import customerForm
in your views.py file
The form is in models.py (*), so you should be doing from mtcc_customer_db.models import customerForm.
(*) note that it should probably be in forms.py anyway, but still.