I have been trying to make a relationship between two table and have a QuerySelectFiled to select a field from the other table, I have managed to do so, but the problem came when I wanted to submit the field I keep getting :
InterfaceError: <unprintable InterfaceError object>
after debugging the issue I found out that when the form is submitted the value of the field is being submitted not the id, I have solved that by saying in my model
self.firstAuthor = firstAuthor.id
solved the issue but if I choose the empty value it will break because the empty field does not have property id.
so can someone suggest how to do that?
here is my form:
from wtforms_alchemy import QuerySelectField, QuerySelectMultipleField
from ....module1.authors.author.authorModel import Author
from flask_wtf import FlaskForm
from wtforms import SubmitField, HiddenField, BooleanField, SelectField, StringField, FileField, IntegerField, DateTimeField
from datetime import datetime
from wtforms.validators import DataRequired
def getAuthor():
return Author.query
class PublicationsForm(FlaskForm):
id = HiddenField()
title = StringField('Title', validators=[DataRequired()])
category = SelectField('Category', choices=[('', ''),('Journal', 'Journal'), ('Conference', 'Conference'), ('Talk', 'Talk'),('Talk2', 'Talk2'),('Talk3', 'Talk3')])
year = DateTimeField('Year', format='%Y')
publisher = BooleanField('Publisher')
volume = IntegerField('Volume')
issue = IntegerField('Issue')
pages = StringField('Pages')
location = StringField('Location')
note = StringField('Note')
fullCitation = FileField('FullCitation')
fullSource = FileField('FullSource')
finalVersion = FileField('FinalVersion')
firstAuthor = QuerySelectField("FirstAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
secondAuthor = QuerySelectField("SecondAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
thirdAuthor = QuerySelectField("ThirdAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
fourthAuthor = QuerySelectField("FourthAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
fifthAuthor = QuerySelectField("FifthAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
sixthAuthor = QuerySelectField("SixthAuthor", query_factory=getAuthor, get_label="lastName", allow_blank=True, blank_text='')
submit = SubmitField("Save")
here is my model:
from sqlalchemy import Column, Integer, String, Boolean, DateTime
from app import db
class Publications(db.Model):
id = db.Column(Integer, primary_key=True)
title = db.Column(String, nullable=False)
category = db.Column(String, nullable=False)
year = db.Column(db.DateTime)
publisher = db.Column(Boolean)
volume = db.Column(Integer)
issue = db.Column(String)
pages = db.Column(String)
location = db.Column(String)
note = db.Column(String)
fullCitation = db.Column(String)
fullSource = db.Column(String)
finalVersion = db.Column(String)
issue = db.Column(db.Text)
firstAuthor = db.Column(db.Integer, db.ForeignKey('author.id'))
secondAuthor = db.Column(db.Integer, db.ForeignKey("author.id"),nullable=True )
thirdAuthor = db.Column(db.Integer, db.ForeignKey("author.id"),nullable=True )
fourthAuthor = db.Column(db.Integer, db.ForeignKey("author.id"),nullable=True )
fifthAuthor = db.Column(db.Integer, db.ForeignKey("author.id"),nullable=True )
sixthAuthor = db.Column(db.Integer, db.ForeignKey("author.id"),nullable=True )
def __init__(self, title, category, year, publisher, volume, issue, pages, location, note, fullCitation, fullSource, finalVersion, firstAuthor, secondAuthor, thirdAuthor, fourthAuthor, fifthAuthor, sixthAuthor):
self.title = title
self.category = category
self.year = year
self.publisher = publisher
self.volume = volume
self.issue = issue
self.pages = pages
self.location = location
self.note = note
self.fullCitation = fullCitation
self.fullSource = fullSource
self.finalVersion = finalVersion
self.firstAuthor = firstAuthor
self.secondAuthor = secondAuthor
self.thirdAuthor = thirdAuthor
self.fourthAuthor = fourthAuthor
self.fifthAuthor = fifthAuthor
self.sixthAuthor = sixthAuthor
def __repr__(self):
return self.title
here is my view:
from flask import render_template, request, flash, redirect, url_for
from . import publications_blueprint
from .publicationsForm import PublicationsForm
from .publicationsModel import Publications
from app import db
#publications_blueprint.route("/publications", methods=["GET", "POST"])
def createPublications():
form = PublicationsForm(request.form)
publicationss = Publications.query.all()
if request.method == "POST" and form.validate_on_submit():
publications = Publications(form.title.data, form.category.data, form.year.data, form.publisher.data, form.volume.data, form.issue.data, form.pages.data, form.location.data, form.note.data, form.fullCitation.data, form.fullSource.data, form.finalVersion.data, form.firstAuthor.data, form.secondAuthor.data, form.thirdAuthor.data, form.fourthAuthor.data, form.fifthAuthor.data, form.sixthAuthor.data)
db.session.add(publications)
db.session.commit()
flash("Added Publications Successfully")
return redirect(url_for("publications.createPublications"))
return render_template("publications/publications.html", title="Publicationss", form=form, publicationss=publicationss)
#publications_blueprint.route("/updatePublications/<int:publications_id>", methods=["GET", "POST"])
def updatePublications(publications_id):
publications = Publications.query.get(publications_id)
form = PublicationsForm(request.form, obj=publications)
if request.method == "POST" and form.validate_on_submit():
publications.title = form.title.data
publications.category = form.category.data
publications.year = form.year.data
publications.publisher = form.publisher.data
publications.volume = form.volume.data
publications.issue = form.issue.data
publications.pages = form.pages.data
publications.location = form.location.data
publications.note = form.note.data
publications.fullCitation = form.fullCitation.data
publications.fullSource = form.fullSource.data
publications.finalVersion = form.finalVersion.data
publications.firstAuthor = form.firstAuthor.data
publications.secondAuthor = form.secondAuthor.data
publications.thirdAuthor = form.thirdAuthor.data
publications.fourthAuthor = form.fourthAuthor.data
publications.fifthAuthor = form.fifthAuthor.data
publications.sixthAuthor = form.sixthAuthor.data
db.session.commit()
flash("Updated Publications Successfully")
return redirect(url_for("publications.createPublications"))
publicationss = Publications.query.all()
return render_template("publications/publications.html", title="Publications", form=form, publicationss=publicationss)
#publications_blueprint.route("/deletePublications/<int:publications_id>", methods=["GET", "POST"])
def deletePublications(publications_id):
publications = Publications.query.get(publications_id)
db.session.delete(publications)
db.session.commit()
return redirect(url_for("publications.createPublications"))
In a similar case, I also use allow_blank=True in the model for a QuerySelectField search_target. I check manually if there was something selected in the view:
if formfilter.search_target.data:
search_target = formfilter.search_target.data.id
else:
....
Related
I have a permission in Django Rest Framework:
from annoying.functions import get_object_or_None
from django.utils.translation import ugettext_lazy as _
from rest_framework import permissions
from restaurants.models import Restaurant
class TableBelongsToRestaurantPermission(permissions.BasePermission):
"""
Permission to check if the table belongs to the restaurant in the request. This ensures
(together with the UserOwnsRestaurantPermission) that owner can change the QR code of a
restaurant that he doesn't own.
"""
message = TABLE_BELONGS_TO_RESTAURANT_PERMISSION_DENIED_MESSAGE
def has_object_permission(self, request, view, obj):
if not obj.table:
return True
slug = request.data.get("restaurant_slug", "")
restaurant = get_object_or_None(Restaurant, slug=slug)
if restaurant:
return restaurant.table_set.filter(id=obj.table.id).exists()
return False
And now, I wrote tests for this:
from unittest import mock
from allauth.account.models import EmailAddress
from django.contrib.auth import get_user_model
from django.test import TestCase
from addresses.models import (Address, City, Country, PostalCode, State,
StreetName)
from core.utils import QR_CODE_FUNCTIONS
from employments.models import Employment
from licenses.models import RestaurantLicense
from profiles.models import UserOwnerProfile
from qrcodeproperties.models import QRCodePropertyCheckinUser
from restaurants.models import Restaurant
from tables.models import Table
from ...models import QRCode, QRCodeFunction
from ..permissions import TableBelongsToRestaurantPermission
User = get_user_model()
USER_OWNER_EMAIL = "owner#burgergrill.de"
USER_OWNER_NAME = "Owner"
USER_PASSWORD = "test1234test"
ISO_ALPHA_2_CODE = "DE"
STATE_NAME = "NRW"
CITY_NAME = "Köln"
STREET_NAME = "Burgerstraße"
POSTAL_CODE = "32062"
STREET_NUMBER = "119"
RESTAURANT_NAME = "Burgergrill"
RESTAURANT_SLUG = "burgergrill"
TABLE_NUMBER = 1
OTHER_RESTAURANT_NAME = "Extrablatt"
OTHER_RESTAURANT_SLUG = "extrablatt"
class TableBelongsToRestaurantPermissionTestCase(TestCase):
def setUp(self):
self.permission = TableBelongsToRestaurantPermission()
owner_user = User.objects.create_user(
email=USER_OWNER_EMAIL,
name=USER_OWNER_NAME,
password=USER_PASSWORD
)
self.owner_user = owner_user
owner = UserOwnerProfile.objects.create(user=owner_user)
owner.save()
self.owner = owner
emailaddress = EmailAddress.objects.create(
user=owner_user,
email=owner_user.email,
verified=True,
primary=True
)
emailaddress.save()
self.emailaddress = emailaddress
country = Country.objects.create(
country=ISO_ALPHA_2_CODE
)
country.save()
self.country = country
state = State.objects.create(
name=STATE_NAME,
country=self.country
)
state.save()
self.state = state
city = City.objects.create(
name=CITY_NAME,
country=self.country,
state=self.state
)
city.save()
self.city = city
street_name = StreetName.objects.create(
name=STREET_NAME,
city=self.city
)
street_name.save()
self.street_name = street_name
postal_code = PostalCode.objects.create(
code=POSTAL_CODE,
city=self.city
)
postal_code.save()
self.postal_code = postal_code
address = Address.objects.create(
country=self.country,
state=self.state,
city=self.city,
postal_code=self.postal_code,
street_name=self.street_name,
street_number=STREET_NUMBER
)
address.save()
self.address = address
restaurant = Restaurant.objects.create(
name=RESTAURANT_NAME,
address=self.address
)
restaurant.save()
self.restaurant = restaurant
qr_code = QRCode.objects.create()
qr_code.save()
self.qr_code = qr_code
self.request = mock.MagicMock(
user=owner_user,
kwargs={"slug": RESTAURANT_SLUG}
)
self.view = mock.MagicMock()
def test_permissions_table_belongs_to_restaurant_denied_when_table_belongs_to_different_restaurant(self):
"""Test if a user gets permission denied if the qr code's table belongs to another restaurant."""
restaurant = Restaurant.objects.create(name=OTHER_RESTAURANT_NAME, address=self.address)
restaurant.save()
table = Table.objects.create(table_number=TABLE_NUMBER, restaurant=restaurant)
table.save()
prev_count = Table.objects.all().count()
qr_code_function = QRCodeFunction.objects.create(
qr_code=self.qr_code,
qr_code_function=QR_CODE_FUNCTIONS.checkin_user
)
qr_code_function.save()
qr_code_property = QRCodePropertyCheckinUser(
qr_code=self.qr_code,
table=table,
)
qr_code_property.save()
self.assertFalse(self.permission.has_object_permission(
request=self.request, view=self.view, obj=self.qr_code
))
def test_permissions_table_belongs_to_restaurant_granted_when_table_belongs_to_same_restaurant(self):
"""Test if a user gets permission granted if the qr code's table belongs to the same restaurant."""
table = Table.objects.create(table_number=TABLE_NUMBER, restaurant=self.restaurant)
table.save()
prev_count = Table.objects.all().count()
qr_code_function = QRCodeFunction.objects.create(
qr_code=self.qr_code,
qr_code_function=QR_CODE_FUNCTIONS.checkin_user
)
qr_code_function.save()
qr_code_property = QRCodePropertyCheckinUser(
qr_code=self.qr_code,
table=table,
)
qr_code_property.save()
self.restaurant.refresh_from_db()
print(table.restaurant == self.restaurant)
print(self.qr_code.table)
print(self.restaurant.table_set)
self.assertTrue(self.permission.has_object_permission(
request=self.request, view=self.view, obj=self.qr_code
))
def test_permissions_table_belongs_to_restaurant_granted_when_qr_code_without_table(self):
"""Test if a user gets permission granted if the qr code has no table."""
self.assertTrue(self.permission.has_object_permission(
request=self.request, view=self.view, obj=self.qr_code
))
The problem is that the second test (test_permissions_table_belongs_to_restaurant_granted_when_table_belongs_to_same_restaurant) fails. The print statements give out True, 1 Pontgrill and tables.Table.None respectively. That means that for some reason even though I did .refresh_from_db() the data for the restaurant does not update and the test fails because it Django thinks there are no relations from Table to Restaurant.
How can you refresh relations and fix the test?
I am facing a strange problem while implementing ChoiceField and UpdateView in django. I have made a small clip showing the problem that I am facing. Please watch it with subtitles/cc enabled. It will give an idea about the problem I am facing. https://youtu.be/M36TnlJvrZs. The problem goes like this.....
During CreateView, I set the 'gender' ChoiceField as 'Female'. But in UpdateView it pre-populates the 'gender' ChoiceField as Male.
However, The ListView renders the 'gender' field properly as 'Female'.
And strangely, the django admin panel, displays no value at all for the 'gender' field.
Here are all the codes:
models.py:
from django.db import models
from django.core.urlresolvers import reverse
gender_choices = (('Male', 'Male'), ('Female', 'Female'))
class Birth(models.Model):
full_name = models.CharField(max_length = 100)
gender = models.CharField(max_length=6, choices=gender_choices)
date_of_birth = models.DateField()
place_of_birth = models.CharField(max_length = 50)
mother_name = models.CharField(max_length = 50)
father_name = models.CharField(max_length = 50)
address_at_time_of_birth = models.TextField(max_length = 500)
permanent_address = models.TextField(max_length = 500)
registration_no = models.CharField(max_length = 50)
remarks = models.CharField(max_length = 200)
registration_date = models.DateField()
issue_date = models.DateField()
def get_absolute_url(self):
return reverse('birth:birth_update', kwargs={'pk':self.pk})
#return reverse('birth:birth_home')
def __str__(self):
return self.full_name
forms.py:
from django import forms
from .models import *
class BirthForm(forms.ModelForm):
full_name = forms.CharField()
gender = forms.ChoiceField(choices = gender_choices, widget=forms.Select())
date_of_birth = forms.DateField(widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
place_of_birth = forms.CharField()
mother_name = forms.CharField()
father_name = forms.CharField()
address_at_time_of_birth = forms.CharField(widget = forms.Textarea())
permanent_address = forms.CharField(widget = forms.Textarea())
registration_no = forms.CharField(required = False)
registration_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
remarks = forms.CharField(required = False)
issue_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
class Meta:
model = Birth
fields = '__all__'
views.py:
from django.views.generic import ListView, CreateView, UpdateView
from .models import *
from .forms import *
from datetime import date
class BirthHome(ListView):
template_name = 'birth/birth_home.html'
model = Birth
context_object_name = 'birth_objects'
paginate_by = 20
def get_queryset(self):
return Birth.objects.all().order_by('-id')
class NewBirth(CreateView):
model = Birth
form_class = BirthForm
#fields = '__all__'
template_name = 'birth/birth_add.html'
def form_valid(self, form):
obj = form.save(commit = False)
if not obj.registration_date:
obj.registration_date = date.today()
if not obj.issue_date:
obj.issue_date = date.today()
if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
form.add_error('date_of_birth', 'Please enter a valid date')
return super(NewBirth, self).form_invalid(form)
obj.full_name = obj.full_name.upper()
obj.gender = obj.gender.upper()
obj.place_of_birth = obj.place_of_birth.upper()
obj.mother_name = obj.mother_name.upper()
obj.father_name = obj.father_name.upper()
obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
obj.permanent_address = obj.permanent_address.upper()
if obj.remarks:
obj.remarks = obj.remarks.upper()
self.object = form.save()
return super(NewBirth, self).form_valid(form)
class BirthUpdate(UpdateView):
model = Birth
form_class = BirthForm
template_name = 'birth/birth_update.html'
def form_valid(self, form):
obj = form.save(commit = False)
if not obj.registration_date:
obj.registration_date = date.today()
if not obj.issue_date:
obj.issue_date = date.today()
if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
form.add_error('date_of_birth', 'Please enter a valid date')
return super(BirthUpdate, self).form_invalid(form)
obj.full_name = obj.full_name.upper()
obj.gender = obj.gender.upper()
obj.place_of_birth = obj.place_of_birth.upper()
obj.mother_name = obj.mother_name.upper()
obj.father_name = obj.father_name.upper()
obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
obj.permanent_address = obj.permanent_address.upper()
if obj.remarks:
obj.remarks = obj.remarks.upper()
self.object = form.save()
return super(BirthUpdate, self).form_valid(form)
I searched a lot and experimented a lot as well, but to no avail. Seriously need help. Also if this approach is not correct, what should be the correct working approach??
Solved!
So after lots of experimenting, I realized what the problem was!! It was in models.py file:
Since, I was converting all my inputs to uppercase, the 'choices' tuple also needed to have the values in uppercase. Initially the gender_choices tuple read like this:
gender_choices = (('Male', 'Male'), ('Female', 'Female'))
And in my views, I was making the gender as uppercase, thus causing mis-match in the declared tuple data and form data.
So, I changed the tuple to this:
gender_choices = (('MALE', 'MALE'), ('FEMALE', 'FEMALE'))
Works like a Charm!! Cheers.... And thanx for all the help and suggestions. Any feedback is always welcome :)
I am trying to paginate a secondary table for Client but it doesn't work, the results always more than the per_page parameter that by default shows only three items per page .
Here is my models.py:
subscribers = db.Table(
'clients_subscribed',
db.Column('client_id', db.Integer, db.ForeignKey('client.id', ondelete='CASCADE')),
db.Column('user_id', db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'))
)
class Client(db.Model, UserMixin):
id = db.Column(db.Integer(), primary_key=True)
public_id = db.Column(db.String(50), default=uuid.uuid4)
name = db.Column(db.String())
subscribed_users = db.relationship(
'User',
secondary=subscribers,
backref=db.backref('user', passive_deletes=True, lazy='dynamic')
)
Here is also my views.py :
from flask import current_app
current_app.config['SUBSCRIBERS_PER_PAGE'] = 3
#api_route.route('/client/subscribers/<string:category>/<string:client_id>', methods=['GET'])
#token_required
def subscribers(current_user, category, client_id):
if request.method == 'GET':
page = request.args.get('page', 1, type=int)
client = Client.query.filter_by(public_id=client_id).first()
if not client:
raise InvalidUsage(u'404, not found!', status_code=404)
pagination = # Paginate Client.subscribed_users
psubscribers = pagination.items
subscribers = {}
prev = None
if pagination.has_prev:
prev = url_for('api.subscribers', category=category, client_id=client_id, page=page-1, _external=True)
next = None
if pagination.has_next:
next = url_for('api.subscribers', category=category, client_id=client_id, page=page+1, _external=True)
for client in client.subscribed_users:
subscribers_case = {
'id': client.id,
'public_id': client.public_id,
'image': '/static/img/'+client.image if client.image else '/static/img/logo.png',
'name': client.name,
}
subscribers[client.public_id] = subscribers_case
return jsonify({
'subscribers' : subscribers,
'prev' : prev,
'next': next,
'count' : pagination.total
})
return jsonify({'error' : 'No data!'})
Also here is the class User in models:
class User(db.Model, UserMixin):
__tablename__ = 'user'
id = db.Column(db.Integer(), primary_key=True)
public_id = db.Column(db.String(50), default=uuid.uuid4)
name = db.Column(db.String())
family = db.Column(db.String())
bio = db.Column(db.String())
tele = db.Column(db.String(), unique=True)
password = db.Column(db.String())
clients = db.relationship('Client', backref='user', passive_deletes=True, lazy='dynamic')
news = db.relationship('News', backref='user', passive_deletes=True, lazy='dynamic')
notifications = db.relationship('Notification', backref='user', passive_deletes=True, lazy='dynamic')
image = db.Column(db.String(), nullable=True)
slug = db.Column(db.String())
roles = db.relationship(
'Role',
secondary=roles,
backref=db.backref('users', lazy='joined',
passive_deletes=True,
single_parent=True)
)
subscribed_clients = db.relationship(
'Client',
secondary=subscribers,
backref=db.backref('client', passive_deletes=True, lazy='joined')
)
Any suggestions guys how to make that work !!!
You need to use lazy=dynamic in the relationship in order to get a Query object back. Documentation here, and another StackOverflow question about this here.
I have been working on a project in which I have to point out the expenses that the workers of a company have.
For this I have created two models, workers and expenses, in which expenses has a foreign key to workers, in the field: "nomTreballador".
When I try to save it in the db I get the error: "Cannot assign "u'Joan Manel'": "despesa.nomTreballador" must be a "treballador" instance."
My models.py:
from __future__ import unicode_literals
from django.db import models
from django.core.validators import RegexValidator
KILOMETRATGE = 'KM'
DINAR = 'DIN'
AUTOPISTA = 'AP'
MANTENIMENTPC = 'PC'
GASTOS = (
(KILOMETRATGE, 'Kilometres'),
(DINAR, 'Dinar'),
(AUTOPISTA, 'Autopista peatge'),
(MANTENIMENTPC, 'Manteniment de pc')
)
NIF = 'NIF'
NIE = 'NIE'
DNI = 'DNI'
TIPUSDOC = (
(DNI, 'DNI'),
(NIF, 'NIF'),
(NIE, 'NIE')
)
class treballador(models.Model):
nom = models.CharField(max_length=150, null=False, unique=True)
cognom = models.CharField(max_length=150, null=False)
tipusDocID = models.CharField(max_length=3, choices=TIPUSDOC, null=False)
docId = models.CharField(max_length=9, null=False)
tlf_regex = RegexValidator(regex=r'^\d{9,9}$',message="Phone number must be entered in the format: '+999999999'. Up to 9 digits allowed.")
tlf = models.CharField(validators=[tlf_regex], blank=True, max_length=9) # validators should be a list
correu = models.EmailField(max_length=254)
ciutat = models.CharField(max_length=150)
dataDAlta = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return unicode(self.nom) or 'u'
class despesa(models.Model):
nomTreballador = models.ForeignKey(treballador, to_field='nom')
tipusDeGast = models.CharField(max_length=3, choices=GASTOS)
quantia = models.DecimalField(max_digits=5, decimal_places=2)
data = models.DateTimeField()
def __unicode__(self):
return unicode(self.nomTreballador) or 'u'
My forms.py:
from django import forms
from functools import partial
from .models import despesa, treballador
DateInput = partial(forms.DateInput, {'class':'datepicker'})
class desModelForm(forms.ModelForm):
data = forms.DateField(widget=DateInput(format='%d/%m/%Y'), label="Data de la despesa", input_formats=['%d/%m/%Y'])
iquery = treballador.objects.values_list('nom', flat=True).distinct()
iquery_choices = [('','None')] + [(treballador,treballador) for treballador in iquery]
nomTreballador = forms.ChoiceField(choices=iquery_choices)
class Meta:
model= despesa
fields= ["nomTreballador","tipusDeGast","quantia","data"]
def clean_despesa(self):
despeses = self.cleaned_data.get("tipusDeGast")
return despeses
def clean_date(self):
date = self.cleaned_data.get("data")
return date
def clean_quantia(self):
quantia = self.cleaned_data.get("quantia")
return quantia
def clean_nom(self):
nomTreballador = self.cleaned_data.get("nomTreballador")
return nomTreballador
My views.py:
from django.shortcuts import render
from .forms import desModelForm, treballadorForm
from .models import treballador, despesa
def home(request):
form = desModelForm(request.POST or None)
context = {
"gast_form": form
}
if form.is_valid():
desp = form.save(commit=False)
desp.save()
return render(request, "imputacioDespeses.html", context)
I've tried solutions of similar questions but I have not managed to solve it
Thank you!!
You are getting this error because you are passing a text string to be used as the nomTreballador foreign key, while you should be passing a treballador instance.
It looks like you're trying to restrict the available choices to a set of distinct trebelladors by using a forms.ChoiceField, but a better way to do this with a ModelForm is to change the queryset attribute of the nomTreballador field. You do this in the form's init method:
self.fields['nomTreballador'].queryset = treballador.objects.all().distinct()
Also you should check the clean methods you've implemented because not all of them map to an existing field.
I am using QuerySelectField in my forms.py and when submitting it I get the following error:
InterfaceError: (InterfaceError) Error binding parameter 8 - probably unsupported
type. u'INSERT INTO menu (title, title_eng, alias, menu_type, ordering,
check_out_time, access, published, parent_id, image, content, content_eng,
metades, metakey) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
(u'\u0423\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f',
u'terms of connecting', u'terms', u'simple', 4, '2014-01-23 00:00:00.000000',
u'public', u'1', <app.models.Menu object at 0x7fe158171990>, u'url/folder/image.jpg',
u'asd', u'asd', u'asd', u'asd')
I googled it and found out that the issue is that the returned value of QuerySelectField is object and I have to convert it to string, but I couldnt. Can you please help me with that issue?
here is my forms.py:
def menu_list():
return Menu.query
class Add_menu_form(Form):
"""Add_menu_form is used to add/edit menu"""
title = TextField(u'Название меню', [validators.Length(min=1, max=250), validators.Required()])
title_eng = TextField(u'Название меню на английском', [validators.Length(min=1, max=250), validators.Required()])
alias = TextField(u'Короткое название')
menu_type = SelectField(u'Тип меню',
choices=[('simple', u'обычное'),
('blog', u'блог'),
('products', u'продукция'),
('gallery', u'галерея')])
ordering = IntegerField(u'Позиция')
check_out_time = DateField(u'Дата публикации')
access = SelectField(u'Доступ',
choices=[('public', u'открытый'),
('registered', u'для зарегистрированных'),
('admin', u'для администратора')])
published = SelectField(u'Опубликовать',
choices=[('1', u'да'),
('0', u'нет')])
parent_id = QuerySelectField(u'Родительская группа',
query_factory = menu_list,
get_pk = lambda a: a.id,
get_label = lambda a: a.title,
allow_blank=True)
image = TextField(u'Заглавная картинка')
content = TextAreaField(u'Содержание', [validators.Required()])
content_eng = TextAreaField(u'Содержание на английском', [validators.Required()] )
metades = TextAreaField(u'HTML описание')
metakey = TextAreaField(u'HTML ключевые слова')
this is my models.py:
class Menu(db.Model):
"""Menu is used for websites navigation titles.
eg. Home/About Us/Blog/Contacts/and etc"""
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(255))
title_eng = db.Column(db.String(255))
alias = db.Column(db.String(255))
menu_type = db.Column(db.String(10))
#menu type: simple, blog, gallery, contacts, products
ordering = db.Column(db.SmallInteger, default = '1')
check_out_time = db.Column(db.DateTime)
access = db.Column(db.String(30))
#access: user, reductor, manager, administrator
published = db.Column(db.SmallInteger, default = '1')
parent_id = db.Column(db.Integer)
image = db.Column(db.String(350))
content = db.Column(db.String)
content_eng = db.Column(db.String)
metades = db.Column(db.String(350))
metakey = db.Column(db.String(350))
def __init__(self, title, title_eng, alias,
menu_type, ordering, check_out_time, access,
published, parent_id, image, content, content_eng,
metades, metakey):
self.title = title
self.title_eng = title_eng
self.alias = alias
self.menu_type = menu_type
self.ordering = ordering
self.check_out_time = check_out_time
self.access = access
self.published = published
self.parent_id = parent_id
self.image = image
self.content = content
self.content_eng = content_eng
self.metades = metades
self.metakey = metakey
# __str__ is a special method, like __init__, that is
# supposed to return a string representation of an object.
def __str__(self):
return '%.d' % (self.id)
and the views.py:
#admin.route('/manage/add_menu', methods = ['GET', 'POST'])
#login_required
def add_menu(parent = ''):
form = Add_menu_form()
if form.validate_on_submit():
new_menu = Menu(
form.title.data,
form.title_eng.data,
form.alias.data,
form.menu_type.data,
form.ordering.data,
form.check_out_time.data,
form.access.data,
form.published.data,
form.parent_id.data,
form.image.data,
form.content.data,
form.content_eng.data,
form.metades.data,
form.metakey.data)
form.populate_obj(new_menu)
db.session.add(new_menu)
db.session.commit()
flash('New menu was added successfully.')
return redirect(url_for('cabinet.manage', current = 'menu_settings'))
return render_template('admin/manage/site_figuration/add_menu.html',
title = 'Internet market',
parent = parent,
form = form)
Finally the issue is solved after hours of googling. the issue was about QuerySelectField. The problems was that when retrieving form.parent_id.data it actually returned a query object, whie I need a string vaue. So I converted the value to string and added submitted it to database:
a = str(form.parent_id.data)
if form.validate_on_submit():
new_menu = Menu(
form.title.data,
form.title_eng.data,
form.alias.data,
form.menu_type.data,
form.ordering.data,
form.check_out_time.data,
form.access.data,
form.published.data,
a, #form.parent_id.data,
form.image.data,
form.content.data,
form.content_eng.data,
form.metades.data,
form.metakey.data)
form.populate_obj(new_menu)
db.session.add(new_menu)
db.session.commit()