I'm using Django 1.3 and South those should be useful information. My problem is that, when saving the form it says:
ValueError at /reportforms/c13
Cannot assign "u'3'": "c13.job" must be a "joblist" instance.
Request Method: POST
Request URL: http://localhost:9000/reportforms/c13
Django Version: 1.3
Exception Type: ValueError
Exception Value: Cannot assign "u'3'": "c13.job" must be a "joblist" instance.
Exception Location: /media/Django/path_env/local/lib/python2.7/site-packages/django/db/models/fields/related.py in __set__, line 331
Python Version: 2.7.3
Any idea what's wrong with this?
models.py
class joblist(models.Model):
job_english = models.CharField(_('Job name in english'), max_length=255, default="")
job_hungarian = models.CharField(_('Job name in hungarian'), max_length=255, default="")
class c13(models.Model):
job = models.ForeignKey(joblist, verbose_name=_('Job'))
forms.py
class C13Form(ModelForm):
job = forms.ChoiceField(choices=[(item.pk, item.job_english) for item in joblist.objects.all()])
class Meta:
model = c13
exclude = ('added_by')
views.py
form = C13Form(request.POST)
if form.is_valid():
new_c13 = c13.objects.create(
job = joblist.objects.get(pk=form.cleaned_data['job']),
year = form.cleaned_data['year'],
needlestick_injuries = form.cleaned_data['needlestick_injuries'],
staff_beginning = form.cleaned_data['staff_beginning'],
staff_end = form.cleaned_data['staff_end'],
working_hours_beginning = form.cleaned_data['working_hours_beginning'],
working_hours_end = form.cleaned_data['working_hours_end'],
added_by = request.user,
)
new_c13.save()
return render_to_response('filled_out.html', {}, context_instance=RequestContext(request))
else:
form = C13Form(request.POST)
return render(request, 'c13.html', { 'form': form })
Maybe you have to use ModelChoiceField, see https://docs.djangoproject.com/en/dev/ref/forms/fields/#django.forms.ModelChoiceField
job = forms.ModelChoiceField(queryset=joblist.objects.all())
Related
I've got problem with saving data to non-default database.
In models.py I've got:
grid_fs_storage = GridFSStorage(collection='tab_userinquiries', base_url='mydomain.com/userinquiries/',database='mongo_instance')
class DocsUserInquiry(models.Model):
query_pk = models.CharField(blank=False, null=False, unique=True, max_length=150, primary_key=True) # auto - calculated
query_file_md5 = models.CharField(blank=False, null=True, unique=False, max_length=200) # auto - calculated
query_file = models.FileField(upload_to='userinquiries',storage=grid_fs_storage,null=True) # auto from form
In views.py:
class UploadInquiryFileView(CreateView,LoginRequiredMixin):
model=DocsUserInquiry
template_name ='new_inquiry.html'
success_message = "You've added your new Token successfully"
form_class = UploadInquiryFileForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
file_name = request.FILES['query_file'].name
print(f'file...{file_name}')
q_pk = random_id()
file_in = self.request.FILES.get('query_file')
f_md5 = calculate_md5(file_in)
form.instance.query_pk = q_pk
form.instance.query_file_md5 = f_md5
form.save()
return HttpResponse(self.success_message)
The problem is every time when I submit form I've got
Exception Type: TypeError
Exception Value: database must be an instance of Database
I've tried added this to post method:
instance = form.save(commit=False)
instance.save(using='mongo_instance')
but the error is the same.
Any ideas how to resolve this issue?
NOTE:
This issue is related only with modelform or when I use custom list of fields in view. When I'm using CreateView without ModelForm but with fields = 'all' and additionally with the logic passed to form_valid method of the view instead of post everything works fine. Then files are added to my mongo db.
After some tests I've figured out the problem is in gridfs. After making small change in FileField I got expected result.
I had to delete upload_to and storage from this field in models.py. This saves data from my form into mongo but without the file itself. To do that I had to add in post method of my CreateView connection to mongo via MongoClient and save file in such separate way.
Completely don't know what's the issue with gridfs storage pointed directly in the model's FileField.
I am working on a django web app.
everything is working fine on my local machine and then pushed the code live on Heroku. but it doesn't work on the live server.
it gives the following error when I try to post a .csv file:
DataError at /freshleadaction
value too long for type character varying(20)
I have PostgreSQL database integrated. I deleted the migrations and then migrated the whole schema again. I think the problem is either PostgreSQL or heroku?
I have two models which are as follows:
class fresh_leads_model(models.Model):
fname = models.CharField(max_length=250)
lname = models.CharField(max_length=250)
street_number = models.CharField(max_length=250)
street_name = models.CharField(max_length=250)
state = models.CharField(max_length=250)
zip_code = models.CharField(max_length=250)
bedrooms = models.CharField(max_length=250)
legal_description = models.CharField(max_length=250)
sq_ft = models.CharField(max_length=250)
address = models.CharField(max_length=250)
orign_ln_amt = models.CharField(max_length=250)
prop_value = models.CharField(max_length=250)
equity = models.CharField(max_length=250)
email = models.CharField(max_length=250)
cell = models.CharField(max_length=250)
submitted_date = models.DateField(auto_now_add=True)
updated_date = models.DateField(auto_now_add=True)
deleted_date = models.DateField(auto_now_add=True)
class cash_buyer_model(models.Model):
fname = models.CharField(max_length=255)
lname = models.CharField(max_length=255)
email = models.CharField(max_length=255)
city = models.CharField(max_length=255)
state = models.CharField(max_length=255)
submitted_date = models.DateField(auto_now_add=True)
updated_date = models.DateField(auto_now_add=True)
deleted_date = models.DateField(auto_now_add=True)
my views.py function:
def upload_fresh_leads(request):
get_type = request.GET['type']
lst = []
if request.method == 'POST':
leads = Fresh_leads_Form(request.POST, request.FILES)
data = request.FILES.getlist('csv')
# data = Fresh_leads_Form(request.FILES)
# csv_file = request.GET['csv']
# df = pd.read_csv(csv_file)
# return HttpResponse(print(df)))
# data = []
# message = 2
# return render(request, 'admin/src/tabs/fresh_leads.html', {'message': message})
if get_type == '1':
if leads.is_valid():
# csv = data['csv']
for d in data:
print('dataaaa :::::::::::', d)
# df = pd.read_csv(d, usecols=['Owner First Name'])
# return HttpResponse(df.to_string())
df = pd.read_csv(
d,
# print('dataaaa :::::::::::', d),
dtype='str',
names=[
'Owner First Name',
'Owner Last Name',
'StreetNumber',
'StreetName',
'State',
'Zip Code',
'Bdrms',
'Legal Description',
'Sq Ftg',
'Address',
'Orig Ln Amt',
'Prop Value',
'Equity',
'Email',
'Cell'
])
# print('data frame', df)
df = df.fillna(0)
df.columns = [
'Owner_FirstName',
'Owner_LastName',
'StreetNumber',
'StreetName',
'State',
'ZipCode',
'Bdrms',
'Legal_Description',
'Sq_Ftg',
'Address',
'Orig_Ln_Amt',
'Prop_Value',
'Equity',
'Email',
'Cell']
json_record = df.reset_index().to_json(orient='records')
lst = json.loads(json_record)
bulk_data = df.to_dict('records')
model_instances = [fresh_leads_model(
fname=i['Owner_FirstName'],
lname=i['Owner_LastName'],
street_number=i['StreetNumber'],
street_name=i['StreetName'],
state=i['State'],
zip_code=i['ZipCode'],
bedrooms=i['Bdrms'],
legal_description=i['Legal_Description'],
sq_ft=i['Sq_Ftg'],
address=i['Address'],
orign_ln_amt=i['Orig_Ln_Amt'],
prop_value=i['Prop_Value'],
equity=i['Equity'],
email=i['Email'],
cell=i['Cell']
)for i in bulk_data]
fresh_leads_model.objects.bulk_create(model_instances)
# message = 2
# return render(request, 'admin/src/tabs/fresh_leads.html', {'data': lst, 'message': message})
return redirect('main:FreshLeadView')
# message = 1
# return render(request, 'admin/src/tabs/fresh_leads.html', {'message': message})
# message = 3
# return render(request, 'admin/src/tabs/fresh_leads.html', {'message': message})
return render(request, 'frontend-layout/500.html')
full error trace back:
DataError at /freshleadaction
value too long for type character varying(20)
Request Method: POST
Request URL: http://www.realtorbit.com/freshleadaction?type=1
Django Version: 3.1.1
Exception Type: DataError
Exception Value:
value too long for type character varying(20)
Exception Location: /app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py, line 84, in _execute
Python Executable: /app/.heroku/python/bin/python
Python Version: 3.6.1
Python Path:
['/app/.heroku/python/bin',
'/app',
'/app/.heroku/python/lib/python36.zip',
'/app/.heroku/python/lib/python3.6',
'/app/.heroku/python/lib/python3.6/lib-dynload',
'/app/.heroku/python/lib/python3.6/site-packages']
I know you said you "deleted the migrations and then migrated the whole schema again," but clearly something must be left over from your original schema.
I would suggest:
Delete the entire database in Heroku if you don't care about the data: heroku pg:reset DATABASE.
Push up your latest code to Heroku (including the new migrations in a new git commit): git push heroku HEAD:main.
Migrate the database: heroku run python manage.py migrate.
First of all, there is no model with max_length=20 in the sources codes that you've provided. So you need to search for it in other models.
Pay attention:
In Python you need to use CamelCase in class names, so make edits like
class cash_buyer_model(models.Model):
->
class CashBuyerModel(models.Model):
Because this is a Model so you no need to use it in the class names:
class CashBuyer(models.Model):
I see that you've mentioned that you've already found the needed field, you need to push updated code on Heroku
Hey guys thanks for your efforts. Actually, I applied all those solutions before posting my problem here but suddenly I got an idea and I removed all my Charfields from my fresh_leads_model and cash_buyer_model and left their parameters empty(I mean without max_length=255). although CharField was working on my local machine but was not working on a live server. so I decided to change it from CharField to TextField without max_length limit so Heroku supported it and everything is working fine now.
def io_simulation(request):
form = SimForm(request.POST)
print('FIRST' + str(request.POST))
if form.is_valid():
form.save()
return render(request, 'App/simulation.html', {'title': 'Simulation'})
This view function shows that my POST data is being sent correctly, but it's not reaching my database. This is the output of the print statement:
FIRST<QueryDict: {'csrfmiddlewaretoken': ['dzowQoB3lk2IOOc19QXQDPZ3soJaxglaP76cURfjB6GMU3VBkHDe7IDhIp2CPpyK'], 'sim_concentration_range': ['3'], 'sim_concentration_range_2': ['4'], 'sim_concentration_range_unit': ['ppm']}>
If I use io_simulation as the action for my form submission then I get a NoReverseMatch error, and I don't get my POST data printed out. If I use this other function as the action:
def save_sim_data(request):
if request.method == 'POST':
request.POST.get('sim_concentration_range')
request.POST.get('sim_concentration_range_2')
request.POST.get('sim_concentration_range_unit')
data=Sim()
data.sim_concentration_range = request.POST.get('sim_concentration_range')
data.sim_concentration_range_2 = request.POST.get('sim_concentration_range_2')
data.sim_concentration_range_unit = request.POST.get('sim_concentration_range_unit')
data.save()
return render(request, 'nowhere.html')
else:
return render(request,'no/errors.html')
Then I do see my POST data get printed (and it's correct (output in blockquote above)), but I still get nothing in my database.
I cannot make any sense of the views structure and debugging. What is going on?
Edits:
Forms.py:
class SimForm(forms.ModelForm):
sim_concentration_range = forms.DecimalField()
sim_concentration_range_2 = forms.DecimalField()
sim_concentration_range_unit = forms.ChoiceField()
class Meta:
model = Sim
fields = ('sim_concentration_range','sim_concentration_range_2','sim_concentration_range_unit')
models.py
class Sim(models.Model):
sim_concentration_range = models.DecimalField(max_digits = 100, decimal_places = 5, default=1)
sim_concentration_range_2 = models.DecimalField(max_digits = 100, decimal_places = 5, default=1)
sim_concentration_range_unit = models.TextChoices('sim_cc_unit', 'ppm ')
STEPS TAKEN FOR SOLUTION
- Remove variable definitions within forms.py SimForm function but outside of Meta class
class SimForm(forms.ModelForm):
class Meta:
model = Sim
fields = ('sim_concentration_range','sim_concentration_range_2','sim_concentration_range_unit')
- Change TextChoices field in models.py Sim class to CharField
- Removed save_sim_data function from views.py and removed action declarations for the form in its html
- Changed URL pattern to use io_simulation view
Because of you are using ModelForm, you don't have to override the fields. so you can just type it like this:
class SimForm(forms.ModelForm):
class Meta:
model = Sim
fields = ('sim_concentration_range','sim_concentration_range_2','sim_concentration_range_unit')
I've just started playing with formsets. No idea what I'm doing at the moment.
I've got to the point where a form with formset is being saved to the database. However, if nothing is selected for the required field "ledger" then validation still passes, and Django throws up "Key error".
My forms.py:
class JournalEntryForm(forms.Form):
date = forms.DateField(widget=DateTypeInput())
description = forms.CharField(required=False)
class LineItemForm(forms.Form):
ledger = forms.ModelChoiceField(queryset=Ledger.objects.all())
description = forms.CharField(required=False)
project = forms.ModelChoiceField(queryset=Project.objects.all(), required=False)
cr = forms.DecimalField(decimal_places=2, required=False)
dr = forms.DecimalField(decimal_places=2, required=False)
My function in views.py. I've marked line 33 which is the line where the "key error" occurrs.
#login_required
def entries_new(request):
# Takes form and returns form set. So we now have a form set.
LineItemFormSet = formset_factory(LineItemForm, extra=2)
if request.method == 'POST':
journal_entry_form = JournalEntryForm(request.POST)
lineitem_formset = LineItemFormSet(request.POST)
if journal_entry_form.is_valid() and lineitem_formset.is_valid():
q0 = JournalEntry(user=request.user, date=journal_entry_form.cleaned_data['date'], type="JE")
q0.save()
for lineitem_form in lineitem_formset:
q1 = LineItem(
journal_entry=q0,
ledger=lineitem_form.cleaned_data['ledger'], #<---- This is line 33 referenced in the error
cr=lineitem_form.cleaned_data['cr'],
dr=lineitem_form.cleaned_data['dr'],
project=lineitem_form.cleaned_data['project'],
)
q1.save()
messages.success(request, "Journal entry successfully saved.")
return HttpResponseRedirect(reverse('journal:entries_show_all') )
else:
journal_entry_form = JournalEntryForm()
lineitem_formset = LineItemFormSet()
context = { 'journal_entry_form': journal_entry_form, 'lineitem_formset': lineitem_formset, }
return render(request, 'journal/entries_new.html', {'journal_entry_form': journal_entry_form, 'lineitem_formset': lineitem_formset})
The error I get in my browser:
KeyError at /journal/entries/new/
'ledger'
Request Method: POST
Request URL: http://localhost/journal/entries/new/
Django Version: 3.0
Exception Type: KeyError
Exception Value:
'ledger'
Exception Location: C:\Users\Philip\CodeRepos\Acacia2\Journal\views.py in entries_new, line 33
Python Executable: C:\Users\Philip\CodeRepos\Acacia2\venv\Scripts\python.exe
Python Version: 3.8.0
Python Path:
['C:\\Users\\Philip\\CodeRepos\\Acacia2',
'C:\\Users\\Philip\\AppData\\Local\\Programs\\Python\\Python38-32\\python38.zip',
'C:\\Users\\Philip\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs',
'C:\\Users\\Philip\\AppData\\Local\\Programs\\Python\\Python38-32\\lib',
'C:\\Users\\Philip\\AppData\\Local\\Programs\\Python\\Python38-32',
'C:\\Users\\Philip\\CodeRepos\\Acacia2\\venv',
'C:\\Users\\Philip\\CodeRepos\\Acacia2\\venv\\lib\\site-packages']
Server time: Thu, 26 Dec 2019 20:42:45 +0000
So after some digging, it turns out that Django does not validate any empty formsets. I added the following init to my form and now I get a nice formerror if an empty formset is submitted:
class LineItemForm(forms.Form):
ledger = forms.ModelChoiceField(queryset=Ledger.objects.all(),)
description = forms.CharField(required=False)
project = forms.ModelChoiceField(queryset=Project.objects.all(), required=False)
cr = forms.DecimalField(decimal_places=2, required=False)
dr = forms.DecimalField(decimal_places=2, required=False)
# This init disallows empty formsets
def __init__(self, *arg, **kwarg):
super(LineItemForm, self).__init__(*arg, **kwarg)
self.empty_permitted = False
I have no idea what the init does (arg, kwargs and super are all still a mystery to me). I copied it from another page. It works though.
Source : Django documentation
Default value for ModelChoiceField is None, even if you specified the queryset attribute. If the form is valid, to me it means than None in Ledger.objects.all() is True! Are you sure you do have Ledger objects in your database?
I designed and built a Django 1.6.2 survey application using a SessionWizardView which is connected to a MySQL database.
The problem is that (as far as I can see) the submitted form data is not getting saved to the database. This is my first time building an application like this or even working with a database.
Could someone take a look at what I have done and my code and point out any mistakes I have made as to why I cannot see any content submitted by my survey form?
The last time I posted a similar question I was told I needed to create a Model for the data and it was suggested I use a ModelForm to create the table and columns in the database. I have done this but I am still not seeing my submitted content
My Process
I created the database in MySQL (Ver 14.14 Distrib 5.6.20) via
Terminal CREATE database django_db; and the tables in it are created
when I run the command python manage.py syncdb.
I can complete my survey both on my local machine and on the public server. No errors and it appears everything works fine
I have setup phpMyAdmin and can see the django_db database and survey_person model. However I can not seem to find any of the data that should be submitted by the form.
I have tried to use the search facility in phpMyAdmin to find any of the form data I submitted but cannot see it
I have exported the database as a .CSV file but it is empty.
If I use the insert facility in phpMyAdmin the data gets saved in the DB and I can return it when I use the search facilities. The same data is also in the CSV file when I export it.
This seem to suggest that I am missing a step somewhere in my application when it comes to submitting content to the DB.
Can anyone tell me where I am going wrong?
My Code
I have tried to limit the below to only relevant code
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_db',
'USER': 'root',
'PASSWORD': 'xxxxxxxxxxxxxxxxx',
'HOST': '127.0.0.1',
#'PORT': '',
}
}
urls.py
url(r'^surveyone/$', SurveyWizardOne.as_view([
SurveyFormA,
SurveyFormB,
SurveyFormC,
....
....
SurveyFormG,
SurveyFormH,
SurveyFormI
])),
forms.py
class SurveyFormA(forms.ModelForm):
birthdate = forms.DateField(widget=extras.SelectDateWidget(years = range(1995, 1900, -1)), required=False)
class Meta:
model = Person
fields = ['sender', 'birthdate', 'sex', 'relationship', 'state']
class SurveyFormB(forms.ModelForm):
class Meta:
model = Person
fields = ['internet_usage', 'smart_phone_ownership', 'smart_phone_usage']
widgets = {'internet_usage' : RadioSelectNotNull,
'smart_phone_ownership' : RadioSelectNotNull,
'smart_phone_usage' : RadioSelectNotNull,
}
class SurveyFormC(forms.ModelForm):
class Meta:
model = Person
fields = ['education', 'wages', 'presentage_savings', 'occupation', 'living']
widgets = {'education' : forms.RadioSelect,
'wages' : forms.RadioSelect,
'presentage_savings' : forms.RadioSelect,
'occupation' : forms.RadioSelect,
'living' : forms.RadioSelect,}
....
....
models.py
sender = models.EmailField(null=True, blank=True, verbose_name='What is your email address?')
birthdate = models.DateField(null=True, blank=True) #overwritten in forms.py so passed no more arguments
SEX = (
('MALE', 'Male'),
('FEMALE', 'Female'))
sex = models.CharField(null=True, blank=True, max_length=100, choices=SEX, verbose_name='What sex are you?')
RELATIONSHIP = (
('SINGLE', "Single"),
('INARELATIONSHIP', "In a relationship"),
('MARRIED', "Married"),
('DIVORCED', "Divorced"),
('SEPARATED', "Separated"),
('WIDOWED', "Widowed"),)
relationship = models.CharField(null=True, blank=True, max_length=100, choices=RELATIONSHIP, verbose_name='What is your relationship status?')
....
....
def __unicode__(self):
return self
views.py
My views.py are the most complex part of my application. Not sure if it necessary to show any but I thought just in case
class SurveyWizardOne(SessionWizardView):
def get_context_data(self, form, **kwargs):
context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)
step = int(self.steps.current)
if step == 0:
self.request.session['path_one_images'] = ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
self.request.session['instruction_task_one_images'] = ['IT1A.jpg', 'IT1B.jpg', 'IT1C.jpg']
self.request.session['instruction_task_two_images'] = ['IT2A.jpg', 'IT2B.jpg', 'IT2C.jpg']
self.request.session['images'] = []
self.request.session['slider_DV_values'] = []
PATH_ONE_IMAGES = self.request.session.get('path_one_images', [])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])
INSTRUCTION_TASK_ONE_IMAGES = self.request.session.get('instruction_task_one_images', [])
INSTRUCTION_TASK_TWO_IMAGES = self.request.session.get('instruction_task_two_images', [])
if step in range (0, 27):
self.request.session['path_one_images'] = PATH_ONE_IMAGES
self.request.session['images'] = images
self.request.session['slider_DV_values'] = slider_DV_values
self.request.session['instruction_task_one_images'] = INSTRUCTION_TASK_ONE_IMAGES
self.request.session['instruction_task_two_images'] = INSTRUCTION_TASK_TWO_IMAGES
if step == 0:
instruction_task_first_image = random.choice(INSTRUCTION_TASK_ONE_IMAGES)
context['display_image'] = instruction_task_first_image
elif step == 1:
instruction_task_second_image = random.choice(INSTRUCTION_TASK_TWO_IMAGES)
context['display_image'] = instruction_task_second_image
elif step == 9:
first_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(first_image)
context['display_image'] = first_image
images.insert(0, first_image)
self.request.session['first_image'] = images[0]
self.request.session.get('first_image')
elif step == 10:
second_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(second_image)
....
....
return context
def done(self, form_list, **kwargs):
return render(self.request, 'Return_to_AMT.html', {
'form_data': [form.cleaned_data for form in form_list],
})
phpMyAdmin
A screenshot of the DB from phpMyAdmin. NOTE: Not the hidden fields at the start are for introduction steps in the survey form, code not shown here for brevity.
Submitting data to a model form does not cause it to be saved automatically. If you want save data from a model form to the database, you need to call its save() method. You could do this in the wizard's done() method.
def done(self, form_list, **kwargs):
# I don't know whether this will work, I am not familiar with your forms.
for form in form_list:
form.save()
# Note the docs suggest redirecting instead of rendering a template.
return render(self.request, 'Return_to_AMT.html', {
'form_data': [form.cleaned_data for form in form_list],
})