Flask Mongoengine validation error with wtfform - flask

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())

Related

Django submit form POST not valid

I am attempting to submit a form to populate the database. I can't get the POST working. It doesn't look valid, but I can't figure out what I need to do to correct it.
I have put some debugging on to see what happens when I click submit & the POST gets sent. I can't figure out how to send created_at or created_by. I assume these are the reason why the POST is not valid and the database is not populating.
models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class Order(models.Model):
order_name = models.CharField(max_length=100, unique=True, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, related_name='Project_created_by', on_delete=models.DO_NOTHING)
def __str__(self):
return self.order_name
class Ce_Base(models.Model):
ce_hostname = models.CharField(max_length=15)
new = models.BooleanField()
location = models.TextField()
order_reference = models.ManyToManyField(Order)
forms.py
from django.forms import ModelForm
from .models import Order
class OrderForm(ModelForm):
class Meta:
model = Order
fields = ['order_name']
views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Order
from .models import Ce_Base
from .forms import OrderForm
#login_required
def home(request):
form = OrderForm()
if request.method == 'POST':
form = OrderForm()
form.instance.created_by = request.user
print(request.POST)
if form.is_valid():
form.save()
context = {
'order': Order.objects.all(),
'form': form,
}
return render(request, 'orchestration/order_create.html', context)
#login_required
def orderprocessing(request):
context = {
'ce_base': Ce_Base.objects.all()
}
return render(request, 'orchestration/order_processing.html', context)
html
{% extends "orchestration/base.html" %}
{% block content %}
<h1>Input Form</h1>
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" >
</form>
<h1>Orders</h1>
{% for each_order in order %}
<p>Order Name: {{ each_order.order_name }}</p>
<p>Created On: {{ each_order.created_at }}</p>
<p>Created By: {{ each_order.created_by }}</p>
{% endfor %}
{% endblock content %}
Here is my terminal output when i hit the submit button
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
May 12, 2022 - 16:15:40
Django version 4.0.2, using settings 'dcn_automation.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
<QueryDict: {'csrfmiddlewaretoken': ['MQVrDwqyT8Y6ARAF9CCyuCSwavz5BAVmi2GdxMgvxFlHmiD1M8Cq6y0VRVummR82'], 'order_name': ['test']}>
If don't pass the data in the form, the validation fails.
form = OrderForm(request.POST)

In Django How to set up dependent dropdown lists

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?

Django3.0.1: after use ForeignKey then show this problem - This field cannot be null

Django3.0.1: after use ForeignKey then show this problem - This field cannot be null.
I'm using Django 3.0.1 and MySQL database.
I've attached the code below - in models.py, views.py, forms.py
models.py:
from django.conf import settings
from django.db import models
# Create your models here.
User = settings.AUTH_USER_MODEL
class BlogPost(models.Model):
user = models.ForeignKey(User, default=1, blank=True, null=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
content = models.TextField(null=True, blank=True)
views.py:
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.http import Http404
from django.shortcuts import render, get_object_or_404
from .models import BlogPost
from .forms import BlogPostForm, BlogPostModelForm
# Create your views here.
# #login_required
#staff_member_required
def blog_post_create_view(request):
# create objects - but how
# ? use a form
form = BlogPostModelForm(request.POST or None)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
form = BlogPostModelForm()
template_name = 'blog/create.html'
context = {
'form': form,
}
return render(request, template_name, context)
forms.py:
from django import forms
from .models import BlogPost
class BlogPostForm(forms.Form):
title = forms.CharField(max_length=120)
slug = forms.SlugField()
content = forms.CharField(widget=forms.Textarea)
class BlogPostModelForm(forms.ModelForm):
class Meta:
model = BlogPost
fields = ['title', 'slug', 'content']
def clean_title(self, *args, **kwargs):
title = self.cleaned_data.get('title')
post_title = BlogPost.objects.filter(title=title)
if post_title.exists():
raise forms.ValidationError("This title has already been used. Please try again.")
return
(terminal)migrations already done:
(venv)
fahim#Lenovo-IP320 MINGW64 /d/(G)/Python/try_django3.0
$ py manage.py makemigrations
No changes detected
(venv)
fahim#Lenovo-IP320 MINGW64 /d/(G)/Python/try_django3.0
$ py manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
No migrations to apply.
(venv)
fahim#Lenovo-IP320 MINGW64 /d/(G)/Python/try_django3.0
$
create.html:
{% extends 'index.html' %}
{% block title %}
Create New Post
{% endblock %}
{% block content %}
{% if title %}
<h1>{{ title }}</h1>
{% endif %}
<form action="." method="post" enctype="multipart/form-data"> {% csrf_token %}
{{ form.as_p }}
<button class="btn btn-success" type="submit">Send</button>
</form>
{% endblock %}
the problem:
This field cannot be null.
clean_<field> methods should return the cleaned/validated value
def clean_title(self, *args, **kwargs):
title = self.cleaned_data.get('title')
post_title = BlogPost.objects.filter(title=title)
if post_title.exists():
raise forms.ValidationError("This title has already been used. Please try again.")
return title

csrf token not showing input fields - Django

I am new to django. am using django==1.11
am trying to create a form which inputs details of users.
my
views.py
from django.shortcuts import render, render_to_response, redirect
from django.template import loader, Template, Context, RequestContext
from forms import UserForm
from django.http import HttpResponse, HttpResponseRedirect
from django.views.decorators import csrf
def action(request):
if request.POST:
form = UserForm(data = request.POST)
if form.is_valid():
form.save(commit = False)
return HTTPResponseRedirect('/rfid/index')
else:
form = UserForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('reg.html', args)
forms.py
from django import forms
from models import UserDetails
class UserForm(forms.ModelForm):
class Meta:
model = UserDetails
fields = '__all__'
reg.html
{% extends "rfid/header.html" %}
{% block content %}
<div class="container">
<form action = "/" method="post">{% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type="submit" name="submit" class="btn btn-default" value="Add User">
</form>
</div>
{% include "rfid/includes/htmlsnippet.html" %}
{% endblock %}
models.py
from django.db import models
# Create your models here.
class UserDetails(models.Model):
GENDER_CHOICES = (('M', 'Male'), ('F', 'Female'))
user_id = models.IntegerField(primary_key = True)
name = models.TextField(max_length = 50)
gender = models.CharField(max_length = 1, choices = GENDER_CHOICES)
dob = models.DateTimeField()
address = models.TextField(max_length = 200)
phone = models.IntegerField()
email = models.EmailField(max_length=254)
photo_url = models.CharField(max_length = 200)
def __str__(self):
return self.name
But it is only showing the submit button. Model-based fields are not displaying. I had gone through some Questions here but was not able to trace out what was the problem. can anyone help me out.
Hope all required details are given. pls, ask if I miss anything.
regards.
Check out the line with form.save(commit=False).
Except you want to give that line a name and later save the name like saved_form=form.save(commit=False) then saved_form.safe, then the commit=False line isn't necessary. I don't know if that is the problem, but will check and revert

Error uploading file in django

I am trying to attach a file in django models, but when I hit submit button the selected file immediately disappears and the form submission fails . What is going wrong here?
forms.py
from django import forms
from .models import IssueNotice
class IssueNoticeForm(forms.ModelForm):
class Meta:
model = IssueNotice
fields = ('title', 'content','issuer','attachment',)
models.py
from django.db import models
from django.utils import timezone
from django import forms
class IssueNotice(models.Model):
title = models.CharField(max_length=300)
content = models.TextField()
attachment = models.FileField(upload_to='attachments')
issuer = models.CharField(max_length=100)
issuer_id = models.ForeignKey('auth.User')
issued_date = models.DateTimeField(default = timezone.now)
def publish(self):
self.issued_date = timezone.now()
self.save()
def __str__(self):
return self.title
views.py
from django.shortcuts import render
from django.utils import timezone
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from .models import IssueNotice
from .forms import IssueNoticeForm
def issue_notice(request):
if request.method == "POST":
form = IssueNoticeForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['attachment'])
notice = form.save(commit = False)
notice.issuer_id = request.user
notice.issued_date = timezone.now()
notice.save()
return redirect('home_page')
else:
form = IssueNoticeForm()
return render(request, 'webadmin/issue_notice.html',{'form':form})
issue_notice.html
{% extends 'webadmin/base.html' %}
{% block content %}
<div class="col-md-8">
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Issue</button>
</form>
{% endblock %}