Django ModelForm; User, this field is required - python

I am having some issues with a (model)form consisting of just a single button. When I try to submit the form this message is displayed:
user
This field is required.
The ModelForm looks like this:
from django.forms import ModelForm
from .models import HulpOproep
class HulpOproepForm(ModelForm):
class Meta:
model = HulpOproep
fields = ['user', ]
The Model looks like this:
class HulpOproep(models.Model):
user = models.ForeignKey(User)
time = models.DateTimeField(auto_now_add=True, verbose_name='Tijd')
def __str__(self):
return '%s %s' % (self.user.username, str(self.time))
def username(self):
return self.user.username
def first_name(self):
return self.user.first_name
def last_name(self):
return self.user.last_name
class Meta:
verbose_name = 'Hulp Oproep'
verbose_name_plural = 'Hulp Oproepen'
The View looks like this:
def verzend_oproep(request):
if request.method == 'POST':
form = HulpOproepForm(request.POST)
if form.is_valid():
oproep = form.save(commit=False)
oproep.user = request.user
oproep.save()
return redirect('portal/index/')
else:
form = HulpOproepForm()
return render(request, 'portal/verzend_oproep.html', {'form': form})
The Template:
{% extends "base.html" %}
{% block head %}
<title>Zorggroep | Hulp Oproep</title>
{% endblock %}
{% block body%}
<h1>Verstuur Hulpoproep</h1>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_P }}
{{ form.errors }}
<button type="submit" class="save btn btn-default">Verstuur</button>
</form>
{% endblock %}
The 'user' in the HulpOproep model is a ForeignKey and should be the currently logged in user's User object. I tried to specify this using the line:
oproep.user = request.user
So what should happen is:
Get the current user's 'User' object and use it as the 'HulpOproepForm.user'. This way the 'HulpOproepForm.user' is the 'HulpOproep.user' and a Foreign Key.
I have followed multiple tutorials and have searched around, but I cannot find a solution. I'm sorry if the answer is logical, but I have been using Django for only 5 days and have 1.5 months of programming experience under my belt.
Thank you!

Thanks PatNowak and Radek!
I did not know the form was waiting for user input instead of code input. I managed to fix it by adding exclude to the ModelForm.
class HulpOproepForm(ModelForm):
class Meta:
model = HulpOproep
exclude = ['user', 'time']

Related

Django / Model Forms

Completely new to all computer programming and trying to build an app that tracks my smoking habits. The first step was creating a Django model called packs:
class packs (models.Model):
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, blank=False)
num_packs = models.SmallIntegerField(max_length=10)
cost_packs = models.DecimalField(max_digits=6, decimal_places=2)
Next I created a forms.py page and this is where I started getting lost:
from django.forms import ModelForm
from .models import packs
class packsForm(ModelForm):
class Meta:
model = packs
fields = ['num_packs', 'cost_packs']
Of course that led to my failure in HTML trying to render a page that has all the form data:
{%block content%}
<div class = "form_pack">
<h3>FORM PACK</h3>
<p>
<form method="POST" action="."> {% csrf_token %}
<input text="cost_pack" name=cost_pack>
{{ form }}
<input type="submit" value="save"/>
</form>
</p>
</div>
{% endblock %}
To help my view.py looks like this:
def packs_create(request):
form=packsForm(request.POST or None)
if form.is_valid():
return render(request, 'pack/index.htmnl', {'form': form})
Now when I refresh the page I don't get the form. Just the one input i put in.
Can someone help me sort out which path I got lost in and where I need to connect the dots? I believe my forms.py is not complete, but not sure where to progress...
Thanks,
DrKornballer
Just update your views.py and forms.py you will get your form and can save the data entered.
views.py
def packs_create(request):
if request.method == "POST":
form = packsForm(request.POST)
if form.is_valid():
form.save(commit = True)
else:
form = PacksForm()
return render(request, 'pack/index.html', {'form': form})
forms.py
class packsForm(ModelForm):
class Meta:
model = packs
fields = ('num_packs', 'cost_packs')

How to pass modelform instance fields that are not intended for user input to template in Django

I'm using formsets to pass several modelforms with existing model instances to a template. I'd like to do something in the template for each form depending on the value of a model field (let's call it field_check) for that instance. Field_check is not intended for user input and a required field.
If I include field_check into my form without rendering it, I can easily access its value. But then after submitting the form Django complains that field_check is required.
What is the recommended way to access the value of field_check without including it as an input field or running into the required field problem?
Models.py
class MyModel(models.Model):
field_check = models.CharField(max_length=50)
user_input_field = models.CharField(max_length=50)
some_type = models.CharField(max_length=50)
Forms.py
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = [
'user_input_field',
'field_check', #having this field here creates problems, since it's not intended for user input
]
MyFormSet = forms.modelformset_factory(MyModel, form = MyModelForm, extra=0)
Views.py
def myview(request):
this_type = 1
formset = MyFormSet(request.POST or None, queryset = MyModel.objects.filter(some_type = this_type))
if request.method == 'POST':
if formset.is_valid():
formset.save()
return render(request, 'some_other_template.html')
context = {'formset':formset}
return render(request, 'mytemplate.html', context)
Template
<form method="post">
{{ formset.management_form }}
{% for form in formset %}
{{form.id}
# here is the part where I check for the value of field_check
{% if form.field_check == 'Some value' %}
Some text
{% else %}
Some other text
{% endif %}
{{form.user_input_field}}
{% endfor %}
<button type="submit">
</form>

Django form are not showing in html template

I'm trying to create a form in Django template but it is just not showing the fields
here is my files
models.py where i created the desired table
class ReportMessage(models.Model):
sender = models.ForeignKey(UserModel, related_name="report_message_sender", on_delete='CASCADE')
message = models.ForeignKey(Message, on_delete='CASCADE')
created_at = models.DateTimeField(auto_now=True)
reason = models.TextField(max_length=1500)
is_read = models.BooleanField(default=False)
forms.py where i created the form to edit only one field in the table
class ReportMessageForm(forms.Form):
class Meta:
model = ReportMessage
fields = ['reason', ]
views.py where i created the view for the form
#login_required
def report_message(request, pk):
current_user = request.user
reported_message = get_object_or_404(Message, pk=pk)
if request.method == "POST":
report_message_form = ReportMessageForm(request.POST)
if report_message_form.is_valid():
model_instance = report_message_form.save(commit=False)
model_instance.sender = current_user
model_instance.message = reported_message
model_instance.save()
return redirect('report_confirm')
else:
report_message_form = ReportMessageForm()
context = {
'report_message_form': report_message_form,
}
return render(request, 'fostania_web_app/report_message.html', context)
def report_confirm(request):
return render(request, 'fostania_web_app/report_confirm.html')
and urls.py where the urls i used for the views
path('report/messages/<int:pk>/', views.report_message, name="report_message"),
path('report/confirm', views.report_confirm, name="report_confirm"),
and finally that is how i used the form in the html template
{% extends 'fostania_web_app/base.html' %}
{% block content %}
{% load static %}
<form action="" method="post" name="ReportMessageForm" align="right">
{% csrf_token %}
{{ report_message_form }}
<input type="submit" class="btn btn-success" style="width: 100px;" value="إرسال" />
</form>
{% endblock %}
and then all what i see in the html page is the submit button and there is no form labels or input or anything.
In your forms.py if you are not using ModelForm then you have to explicitly declare the fields for the forms
reason = forms.Charfield()
Or you can use ModelForm which inherits from the model you specify.
You should specify the model in the Meta class while using ModelForm.You can also specify required fields from the Model in the fields list in Meta class
Class myform(forms.ModelForm)
Class Meta:
model = your_model_name
fields= [reason,]
Cheers
:)
I think that your problem is in your model form because you are using forms.Form and you need to use forms.ModelForm
class ReportMessageForm(forms.ModelForm):
class Meta:
model = ReportMessage
fields = ['reason', ]
def report_confirm(request):
return render(request, 'fostania_web_app/report_confirm.html', context) #add the context
You need to pass in the "context" so that it shows in the template

Django: Form is not saving to database

I've seen similar types of problems on here but I still haven't been able to work out my problem. When I save PhotographerProfileForm in my view, the form is rendered correctly but after clicking update/submit nothing is actually saved.
No errors are shown either.
What I have now are the fields are prepopulated and I would like the ability to save over these in the database, but nothing happens and at the moment you can only update it from the admin panel.
models.py
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class PhotographerProfile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=200)
bio = models.TextField(max_length=500)
def __str__(self):
return self.user.username
User.profile = property(lambda u: PhotographerProfile.objects.get_or_create(user=u)[0])
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def create_profile(sender,instance,created,**kwargs):
if created:
profile, new = PhotographerProfile.objects.get_or_create(user=instance)
urls.py
urlpatterns = [
url(r'^profile/$', 'photoprofile.views.photographer_profile', name = 'photographer_profile'),
url(r'^profile/portfolio/$', 'photoprofile.views.photographer_portfolio', name='photographer_portfolio'),
]
views.py
#login_required
def photographer_profile(request):
photographerProfile = PhotographerProfile.objects.get(user=request.user)
form = PhotographerProfileForm(initial={'bio':photographerProfile.bio, 'location':photographerProfile.location})#This means you can prepoulate it
return render_to_response('photographerprofile.html',{'form':form}, RequestContext(request))
if request.method == 'POST':
form = PhotographerProfileForm(request.POST, instance = request.user.profile,)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/profile')
else:
user = request.user
profile = user.profile
form = PhotographerProfileForm()
return render(request, 'photographerprofile.html', {'form':form})
def photographer_portfolio(request):
photographerProfile = PhotographerProfile.objects.get(user=request.user)
return render_to_response('photographerportfolio.html', {'photographerProfile':photographerProfile}, RequestContext(request))
forms.py
class PhotographerProfileForm(forms.ModelForm):
class Meta:
model = PhotographerProfile
exclude = ('user',)
photographerprofile.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h2> Profile</h2>
{% for field in form %}
{{ field.error}}
{% endfor %}
<form action='/accounts/profile/' method='post'>
{% csrf_token %}
{{form|crispy}}
<input type='submit' value='Update'/>
<p>Click <a href='/accounts/profile/portfolio/'>here</a> to view portfolio. </p>
</form>
{% endblock %}
You return in the third line of your view, before the form has been processed. Remove that line.

Django ~ WSGIRequest with a form added via get_context_data method

I am getting this error when i visit my page:
Caught AttributeError while rendering: 'WSGIRequest' object has no attribute 'get'
The error kicks in on line "17" of my html, which is the line that outputs form.as_p
The html looks like this:
{% extends "base.htm" %}
{% block content %}
{% if story_list %}
{% for story in story_list %}
<div class="Story">
{{ story.title }}
</div>
{% endfor %}
{% else %}
<p>No stories are present - enter one below</p>
{% endif %}
<h3>Create a new story</h3>
<form action="/addStory" method="post">
{% csrf_token %}
{{ form.as_p }} ***THIS IS LINE 17***
<input type="submit" value="Submit"/>
</form>
{% endblock %}
The problem is i have a view that does two things, and from the django tutorials overrode the get_context_data method to add the second item to the django context. Because, um, that's what i'm meant to do, riiiiiiiiight?
#for showing of the stories!
class StoryShowView(ListView):
model = StoryForm
def get_queryset(self):
return getStoryItemsForUser(self.request)
def get_context_data(self, **kwargs):
context = super(StoryShowView,self).get_context_data(**kwargs)
context['form'] = createNewStoryForm(self.request)
return context
Where, well, the method createNewStoryForm just does this:
def createNewStoryForm(request):
return StoryForm(request)
and StoryForm is just this:
class StoryForm(ModelForm):
class Meta:
model = Story
ordering = ['create_date']
and the Story model is a normal model, that probably isn't part of the problem, but, hey, i am a cutting and a pasting, so here goes!
class Story(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
title = models.CharField(max_length=100)
is_closed = models.BooleanField()
is_random = models.BooleanField() # for uncategorised stories. Only one of these.
result = models.CharField(max_length=20) #how did the relo work out?
create_date = models.DateTimeField('date created')
def __unicode__(self):
return self.title
Any ideas what i am doing wrong?
UPDATE:
ah, it was the line::
return StoryForm(request)
I take it i can either pass in a "request.POST" or nothing, is that it?
Probably you're right and you were passing request instead of request.POST, reqest.GET or request.REQUEST to the constructor of your form. See the doc on how to use forms:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
Two problems that I can see. The easy one being that you can simply replace this line:
context['form'] = createNewStoryForm(self.request)
with
context['form'] = StoryForm(request.POST, request.FILES)
Finally shouldn't this:
class StoryShowView(ListView):
model = StoryForm
Be:
class StoryShowView(ListView):
model = Story

Categories