Django Rest Framework Test: How to refresh a relation? - django

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?

Related

graphene-django add additional argument for DjangoFilterConnectionField and pass it to get_queryset

I have added an additional argument called user_type to disposal_request query, and I want to use this argument to add another filter but when I passed it to get_queryset function. I get the following error: get_queryset() missing 1 required positional argument: 'user_type' I'm not sure how to pass the argument properly.
import graphene
import graphene_django
from app.disposer.models import DisposalRequest
from graphene_django.filter import DjangoFilterConnectionField
from graphql_jwt.decorators import login_required
class UserType(graphene.Enum):
as_collector = "as_collector"
as_disposer = "as_disposer"
class DisposalRequestsType(graphene_django.DjangoObjectType):
latitude = graphene.String()
longitude = graphene.String()
class Meta:
model = DisposalRequest
exclude = ("location",)
filter_fields = [
"uuid",
"disposal_status",
]
interfaces = (graphene.Node,)
convert_choices_to_enum = False
#classmethod
#login_required
def get_queryset(cls, queryset, info, user_type):
user = info.context.user
if user_type == UserType.as_collector:
print("as_collector")
return queryset.filter(collector=user)
elif user_type == UserType.as_disposer:
print("as_disposer")
return queryset.filter(disposer=user)
def resolve_latitude(self, _):
return self.location.x
def resolve_longitude(self, _):
return self.location.y
class DisposalQueries(graphene.ObjectType):
disposal_requests = DjangoFilterConnectionField(
DisposalRequestsType, user_type=UserType()
)
I ended up putting the additional filter to resolve_ function and pass **kwargs for additional fields added by DjangoFilterConnectionField
import graphene
import graphene_django
from app.disposer.models import DisposalRequest
from graphene_django.filter import DjangoFilterConnectionField
from graphql_jwt.decorators import login_required
class UserType(graphene.Enum):
as_collector = "as_collector"
as_disposer = "as_disposer"
class DisposalRequestsType(graphene_django.DjangoObjectType):
latitude = graphene.String()
longitude = graphene.String()
class Meta:
model = DisposalRequest
exclude = ("location",)
filter_fields = [
"uuid",
"disposal_status",
]
interfaces = (graphene.Node,)
convert_choices_to_enum = False
def resolve_latitude(self, _):
return self.location.x
def resolve_longitude(self, _):
return self.location.y
class DisposalQueries(graphene.ObjectType):
disposal_requests = DjangoFilterConnectionField(
DisposalRequestsType, user_type=UserType()
)
#staticmethod
#login_required
def resolve_disposal_requests(_, info, user_type, **__):
user = info.context.user
if user_type == UserType.as_collector:
return DisposalRequest.objects.filter(collector=user).all()
elif user_type == UserType.as_disposer:
return DisposalRequest.objects.filter(disposer=user).all()

I'm trying to login my second user Account i.e Member but it's not working and i'm not getting any error or not redirecting to any page in flask

Models.py
from datetime import datetime
from cmrapp import db,login_manager
from flask_login import UserMixin
#login_manager.user_loader
def load_user(user_id):
return Registration.query.get(int(user_id))
class Registration(db.Model,UserMixin):
id = db.Column(db.Integer(),primary_key=True)
regid = db.Column(db.String(),unique=True)
section = db.Column(db.String(),nullable= False)
username = db.Column(db.String(20),unique=True,nullable = False)
password = db.Column(db.String(60),nullable = False)
def __repr__(self):
return f"Registration('{self.username}','{self.regid}')"
class Participation(db.Model):
id = db.Column(db.Integer(),primary_key=True)
pname = db.Column(db.String(20),nullable= False)
pregid = db.Column(db.String(),unique=True)
psection = db.Column(db.String(),nullable=False)
def __repr__(self):
return f"Participation('{self.pname},'{self.pregid}','{self.psection}')"
#login_manager.user_loader
def load_user(mregid):
return Memberdb.query.get(int(mregid))
class Memberdb(db.Model,UserMixin):
id = db.Column(db.Integer(),primary_key=True)
mregid = db.Column(db.String(20),nullable = False,unique=True)
mname = db.Column(db.String(20),unique=True,nullable = False)
mpassword = db.Column(db.String(60),nullable = False)
organizers = db.relationship('Eventdb',backref='owner',lazy=True)
def __repr__(self):
return f"Memberdb('{self.mname}','{self.id}')"
****routes.py****
from flask import render_template,url_for,request,redirect,flash,request
from cmrapp import app,db,bcrypt
from cmrapp.data import fetch
from datetime import datetime,date
from cmrapp.userforms import Registerform,identityform,studentform,memberform,blockform
from cmrapp.models import Registration,Participation,Memberdb
from flask_login import login_user,current_user,logout_user,login_required
#app.route('/')
#app.route('/signup',methods=["GET","POST"])
def signuppage():
if current_user.is_authenticated:
return redirect(url_for('homepage'))
form = Registerform()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = Registration(username = form.username.data, regid = form.regno.data, password =
hashed_password,section=form.section.data )
db.session.add(user)
db.session.commit()
flash(f"Your Account has been Created! {form.username.data}",'success')
return redirect(url_for('sloginpage'))
else:
return render_template('signup.html',title="Sign Up",form=form,consent=consent,diff=diff)
#app.route('/slogin',methods=["GET","POST"])
def sloginpage():
if current_user.is_authenticated:
return redirect(url_for('homepage'))
form = studentform()
if form.validate_on_submit():
user = Registration.query.filter_by(username = form.studentname.data).first()
if user:
if user and bcrypt.check_password_hash(user.password,form.spassword.data):
login_user(user,True)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('homepage'))
else:
flash(f'Login Unsuccessful ! Check Name and Password.','danger')
return render_template('slogin.html',title ='Student Login',form=form)
else:
flash(f'User doesn\'t exist' ,'danger')
return render_template('slogin.html',title ='Student Login',form=form)
#app.route('/msignup',methods=["GET","POST"])
def msignuppage():
form = memberform()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.memberpassword.data).decode('utf-8')
user = Memberdb(mname = form.membername.data, mregid = form.secureid.data, mpassword =
hashed_password )
db.session.add(user)
db.session.commit()
flash('Your Account has been Created','success')
return redirect('mlogin')
else:
return render_template('msignup.html',title="Member Account",form=form)
# user = user1
#app.route('/mlogin',methods=["GET","POST"])
def mloginpage():
form = memberform()
if form.validate_on_submit():
# if form.membername.data == "Lucky" and form.memberpassword.data == "luckyG2611#":
user = Memberdb.query.filter_by(mname = form.membername.data).first()
if user:
if user and bcrypt.check_password_hash(user.mpassword,form.memberpassword.data):
login_user(user,True)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('mlist'))
else:
flash(f'Login Unsuccessful ! Check Name and Password.','danger')
return render_template('mlogin.html',title ='Member Login',form=form)
else:
flash(f'User doesn\'t exist' ,'danger')
return render_template('mlogin.html',title ='Member Login',form=form)
****userform.py****
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,validators,SubmitField,BooleanField,ValidationError,BooleanField,SelectField,DateField,TextAreaField
from wtforms.validators import DataRequired,Length,EqualTo
from cmrapp.models import Registration,Participation,Memberdb
from flask_login import current_user
class Registerform(FlaskForm):
username = StringField('Name',
validators=[DataRequired(),Length(min=2,max =20),validators.regexp('^[a-
zA-Z\s]+$',message="Name contains only string ! Try Again")])
section = SelectField(u'Section',choices=[('1yr-A', 'Ist-A'),('1yr-B', 'Ist-B'), ('1yr-C','Ist-
C'),('2yr-A', 'Sec-A'),('2yr-B', 'Sec-B'), ('2yr-C','Sec-C'),('3yr-A',
'Third-A'),('3yr-B', 'Third-B'), ('3yr-C','Third-C')],validators=
[DataRequired()],validate_choice=False,coerce=str)
regno = StringField('Registration No.',
validators=[DataRequired(), Length(min=10,max=10),validators.regexp('[19]+
[DBCAG]+\d\d\d',message="Use your Respective Regno.")])
password = PasswordField('Password',
validators=[DataRequired(),Length(min=10)])
submit = SubmitField('Sign Up')
def validate_username(self,username):
user = Registration.query.filter_by(username=username.data).all()
if user:
raise ValidationError('Username Already Exist :(')
def validate_regno(self,regno):
regid = Registration.query.filter_by(regid=regno.data).all()
if regid :
raise ValidationError('Regno. Already Exist :(')
class studentform(FlaskForm):
studentname = StringField('Name',
validators=[DataRequired(),Length(min=2,max =20)])
spassword = PasswordField('Password',
validators=[DataRequired(),Length(min=10)])
studentin = SubmitField('Log In')
class identityform(FlaskForm):
identitypswd = PasswordField(validators=[DataRequired(),Length(min=10)])
submit = SubmitField('Want to join')
def validate_regid(self,pregid):
user1 = Participation.query.filter_by(pregid = current_user.regid.data).all()
if user1 :
raise ValidationError('Already Enrolled :(')
class memberform(FlaskForm):
membername= StringField('Member Name:',
validators=[DataRequired(),Length(min=2,max=20),validators.regexp('^[a-
zA-Z\s]+$',message="Name contains only string ! Try Again")])
memberpassword = PasswordField('Password',validators=[DataRequired(),Length(min=10)])
secureid = StringField('UserId',
validators=[DataRequired(),Length(max=10),validators.regexp('[19]+
[BCA1.]+\d\d\d')])
membersubmit = SubmitField('Get In')
def validate_mname(self,mname):
user1 = Memberdb.query.filter_by(mname = mname.data).all()
if user1 is not None:
raise ValidationError('Username Already Exist :(')
def validate_mregid(self,mregid):
mregid = Memberdb.query.filter_by(mregid = mregid.data).all()
if mregid is not None:
raise ValidationError('Already Exist :(')
i have imported all the required module also but it's not working but the first login page is working . if anybody knows about this .Can anyone help me out of this.
You've coded two #login_manager.user_loaders. When you do that multiple times, the last one wins. (See here)
You'll have to choose which of Registration or Memberdb your app will use to represent a logged-in user.

get id not value from SqlAlchemy_wtforms QuerySelectField

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:
....

django-Cannot assign "u'Joan Manel'": "despesa.nomTreballador" must be a "treballador" instance

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.

Django Allauth not saving custom form

I am adding fields to the signup, the user is created and saved but the data aren't reaching the db. There is no custom User model. The additional fields go to a different table, it is a different model.
settings.py
SOCIALACCOUNT_AUTO_SIGNUP = False
ACCOUNT_SIGNUP_FORM_CLASS = 'myapp.forms.UserDataForm'
LOGIN_REDIRECT_URL = '/'
SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'SCOPE': ['email'],
'METHOD': 'js_sdk' # instead of 'oauth2'
}
}
models.py
from django.contrib.auth.models import User
from django.db import models
from django import forms
class UserData(models.Model):
user = models.OneToOneField(User)
year = models.CharField(max_length=4)
month = models.CharField(max_length=2)
day = models.CharField(max_length=2)
hour = models.CharField(max_length=2)
minute = models.CharField(max_length=2)
sec = models.CharField(max_length=2)
latdeg = models.CharField(max_length=2)
latmin= models.CharField(max_length=2)
londeg = models.CharField(max_length=2)
lonmin= models.CharField(max_length=2)
def __unicode__(self):
return self.user.username
forms.py
from myapp.models import UserData
from django.contrib.auth.models import User
from django import forms
from django.forms.widgets import HiddenInput
class UserDataForm(forms.ModelForm):
class Meta:
model = UserData
fields = ('year','month','day','hour','minute','sec','latdeg','latmin','londeg','lonmin')
def signup(self,request, user):
user.username = user.username
user.year = self.cleaned_data['year']
user.month = self.cleaned_data['month']
user.day = self.cleaned_data['day']
user.hour = self.cleaned_data['hour']
user.minute = self.cleaned_data['minute']
user.sec = self.cleaned_data['sec']
user.latdeg = self.cleaned_data['latdeg']
user.latmin = self.cleaned_data['latmin']
user.londeg = self.cleaned_data['londeg']
user.lonmin = self.cleaned_data['lonmin']
user.save()
Ok, solved by myself afte a while I did this with the form signup def:
def signup(self,request,user):
user=User.objects.get(email=request.email)
year = request.POST.get('year', '')
month = request.POST.get('month', '')
day = request.POST.get('day', '')
hour = request.POST.get('hour', '')
minute = request.POST.get('minute', '')
sec = request.POST.get('sec', '')
latdeg = request.POST.get('latdeg', '')
latmin = request.POST.get('latmin', '')
londeg = request.POST.get('londeg', '')
lonmin = request.POST.get('lonmin', '')
userdata_obj = UserData(user=user,year=year, month=month, day=day, hour=hour,minute=minute, sec=sec,latdeg=latdeg,latmin=latmin,londeg=londeg,lonmin=lonmin)
userdata_obj.save()