AttributeError: ProjectUpdateForm object has no attribute 'completed - django-forms

I'm trying to add a checkbox to a form, if true, I want it to add a row to a through model for a manytomanyfield, but I can't access the checkbox variable. Here is the form that I have added it to, and it appears as expected, so half there:
class ProjectUpdateForm(forms.ModelForm):
completed = forms.BooleanField(). # this variable here
class Meta:
model = Update
fields = [
'category',
'update'
]
Here is my view that I was hoping to deal with it:
def project_update_view(request, slug):
obj = Project.objects.get(slug=slug)
if request.method == 'POST':
form = ProjectUpdateForm(request.POST)
form.instance.project = obj
if form.is_valid():
print(f"================{form.completed}") # attempt to find variable
form.save()
return redirect('project-list')
else:
form = ProjectUpdateForm()
context = {
"form": form,
"object": obj
}
return render(request, 'project_portal/project_update.html', context)
This gives me the error in the title. So I now don't understand what an attribute is, I thought it was an aspect of the class represented by a variable. How can I access this checkbox variable so I can work with it please?

This is in the cleaned_data of the form:
def project_update_view(request, slug):
obj = Project.objects.get(slug=slug)
if request.method == 'POST':
form = ProjectUpdateForm(request.POST)
form.instance.project = obj
if form.is_valid():
print(form.cleaned_data['completed'])
form.save()
return redirect('project-list')

Related

How to show the forms field so user can fill

I am trying to create a form where user can create a team. I did the view, the model and the form, But, somehow the template return with only a submit button and I don't know how to solve it. Any help is of great help, thanks.
Here is the view:
def team_create_view(request):
title = 'Create'
form = TeamCreateForm(request.POST or None, request.FILES or None)
coach = get_coach(request.user)
if request.method == 'POST':
if form.is_valid():
form.instance.coach = coach
form.save()
return redirect(reverse("club", kwargs={ 'id': form.instance.id }))
context = {
'title': title,
'form': form
}
return render(request, "team_create.html", context)
Now the form:
class TeamCreateForm(forms.Form):
form = forms.CharField(widget=forms.Textarea)
class Meta:
model = Team
fields = ('form', 'name', 'logo', 'birth', 'coach', 'players')
The model:
class Team(models.Model):
name = models.CharField(max_length=200)
logo = models.ImageField(default="", blank=True, null=True)
birth = models.DateField(default="", blank=True, null=True)
coach = models.ForeignKey(User, on_delete=models.CASCADE, default="", blank=True, null=True)
players = models.ManyToManyField(User, related_name='players')
def __str__(self):
return self.name
And finally the form:
You form render is written in inside the POST method condition. So in GET method does not render.Please try this.
First Method
Here we just change render code to outside of POST method checking if condition.
def team_create_view(request):
title = 'Create'
form = TeamCreateForm(request.POST or None, request.FILES or None)
coach = get_coach(request.user)
if request.method == 'POST':
if form.is_valid():
form.instance.coach = coach
form.save()
return redirect(reverse("club", kwargs={'id': form.instance.id }))
context = {'title': title,'form': form}
return render(request, "team_create.html", context)
Second Method
Here we check if GET method.
def team_create_view(request):
title = 'Create'
form = TeamCreateForm(request.POST or None, request.FILES or None)
coach = get_coach(request.user)
if request.method == 'POST':
if form.is_valid():
form.instance.coach = coach
form.save()
return redirect(reverse("club", kwargs={'id': form.instance.id }))
elif request.method == "GET":
context = {'title': title,'form': form}
return render(request, "team_create.html", context)

Django Formset... saving User with field exclusion

So in this formset the first field saves & updates just fine... but when I want to add a new object, it doesn't work out so well.
#Views.py
def edit_auto(request):
car = Auto.objects.filter(user=request.user)
CarFormSet = modelformset_factory(Auto, form=AutoForm, max_num=3)
if request.method == 'POST':
formset = CarFormSet(request.POST, request.FILES, queryset=car)
if formset.is_valid():
formset.save(commit=False)
formset.user = request.user
formset.save()
return render_to_response('manage_users.html', {'message':'Success! The user has been updated!'}, context_instance=RequestContext(request))
else:
formset = CarFormSet(queryset=car)
return render_to_response('mycar.html', locals(), context_instance=RequestContext(request))
#forms.py
class AutoForm(forms.ModelForm):
class Meta:
model = Auto
user = Auto.user
exclude = ('user',)
Is it something in the template? If it was a single instance of the form, form.user = request.user normally saves but this doesn't. Any suggestions? Thank you for your help.
For the user-assigning step, just iterate over the formset.
...
if request.method == 'POST':
formset = CarFormSet(request.POST, request.FILES, queryset=car)
if formset.is_valid():
formset.save(commit=False)
for form in formset:
form.user = request.user
formset.save()
...

Django: Displaying a form from one model with content from a second model on one page view

I have an irksome little problem with a forum that I am building.
I need to generate a page that contains a form to populate one
model but that page should also display an entry from another related model.
I want the form to populate a new response in the model Responses (see code below).
That model has the model StartMsg as a foreign key. I want the page view (response_form) to display StartMsg.msg that the user is responding to. The problem is that I am using django's built in forms to generate the form and render_to_response to call the page. The render_to_response statement (marked (A)) sends a dictionary containing the form components from the Responses model to the html template.
How do I include info about the model StartMsg into the render_to_response statement (marked
with (A), below)? Is there a better way to accomplish what I am after?
Here are the models:
class StartMsg (models.Model):
msg_title = models.TextField(max_length=500)
msg = models.TextField(max_length=2000)
pub_date = models.DateTimeField('date published')
author = models.ForeignKey(User)
def __unicode__(self):
return self.msg
class Responses (models.Model):
startmsg = models.ForeignKey(StartMsg) #one startmsg can have many responses
response = models.TextField()
responder = models.ForeignKey(User)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.response
Below is the form processing function followed by the form model.
def response_form (request, msg_id):
msg = get_object_or_404(StartMsg, pk=msg_id)
form = MsgRespForm(request.POST or None)
if form.is_valid():
new_rspns = form.save(commit =False)
#retrieve StartMsg entry to assign to the response entry foreign key
message = StartMsg.objects.get(pk=msg_id)
new_rspns.startmsg = message
response = form.cleaned_data['response']
new_rspns.response = response
new_rspns.responder= request.user.username()
new_rspns.pub_date = datetime.now()
new_rspns.save()
return HttpResponseRedirect(reverse('forum.views.forum', )) #if form is processed, view goes here
return render_to_response( #if form not processed, view goes here
'forumresponseform.html',
{'form': form}, (A)
context_instance = RequestContext(request)
)
class MsgRespForm(forms.ModelForm):
# Add Labels to form fields:
response = forms.CharField(label='Your Response',
widget=forms.Textarea(attrs={'cols': 60, 'rows': 10}))
class Meta: #Define what fields in the form
model = Responses
fields = ('response',)
I found a solution that seems to work.
You can make a function that builds a dictionary out of a variable number of model queries then pass that dictionary to the form template on line (A).
def build_dict(request, ** kwargs):
d = dict(user=request.user, ** kwargs)
return d
msg = get_object_or_404(StartMsg, pk=msg_id)
form = MsgRespForm(request.POST or None)
dict = build_dict(request, msg=msg, form=form)
return render_to_response( #if form not processed, view goes here
'forumresponseform.html',
{'form': dict}, (A)
context_instance = RequestContext(request)
)

django form in multiple views

I want my form to display in multiple views with this behaviour:
1.) Form errors are shown in the view that the user submitted the form from.
2.) If form validates, send user back to the view they submitted the form from.
How might I be able to do that?
I'm pretty sure the first behavior is default, if i understand your question correctly. For the second one, if you don't redirect after saving and validation, it should just re-render the view that you submitted from. Placing a success variable is probably good to see if the form saved. Here is an example of using a single form in multiple views.
models.py:
class MyModel(models.Model):
name = models.CharField()
forms.py:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
views.py:
def first_view(request):
success = False
if request.method=="POST":
form = MyModelForm(request.POST)
if form.is_valid():
form.save()
success = True
else:
form = MyModelForm()
context = { 'form':form,
'success': success, }
return render_to_response('first_view_template.html', context,
context_instance=RequestContext(request))
def second_view(request):
success = False
if request.method=="POST":
form = MyModelForm(request.POST)
if form.is_valid():
form.save()
success = True
else:
form = MyModelForm()
context = { 'form':form,
'success': success, }
return render_to_response('second_view_template.html', context,
context_instance=RequestContext(request))
Have you tried the Django Form preview, if I am not wrong it can be used for your purpose

Django Ajax field help

I have a Django application where I'm trying to have a form that populates a drop down dynamically based on a previous dropdown.
simplified Models:
class VehicleMake(models.Model):
make = models.CharField(max_length = 30)
class VehicleModel(models.Model):
model = models.CharField(max_length = 80)
make = models.ForeignKey(VehicleMake)
class Listing(models.Model):
make = models.ForeignKey(VehicleMake)
model = models.ForeignKey(VehicleModel)
Form:
class DynamicChoiceField(ModelChoiceField):
def clean(self, value):
return value
class MyForm(ModelForm):
category = ModelChoiceField(VehicleCategory.objects, widget=forms.Select(attrs={'onchange':'FilterMakes();'}))
make = DynamicChoiceField(VehicleMake.objects,widget=forms.Select(attrs={'disabled':'true','onchange':'FilterModels();'}), empty_label="Select Model")
model = DynamicChoiceField(VehicleModel.objects,widget=forms.Select(attrs={'disabled':'true'}), empty_label="Select Make")
class Meta:
model = Listing
View:
def new_listing(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
form.save()
else:
form = MyForm()
return render_to_response("newlisting.html", {
"form": form,'model_id':model_id,'make_id':make_id
})
I also have some ajax defined for the auto-populate but this is not the problem
When I submit the form I get the following:
Cannot assign "u'2'": "Listing.make" must be a "VehicleMake" instance.
if I try
make=VehicleMake.objects.get(pk=request.POST['make'])
form.fields['make'] = make
then I get
'VehicleMake' object has no attribute 'widget'
After the suggestion of one of the commenter's that the DynamicChoiceField class was the culprit I removed it and set the form objects for ModelChoiceFields with the exact same other parameters. The object appears to pass and validate correctly as well. The extra class existed based on an old tutorial I found. it appears that what the author did there works with the forms.ChoiceField but is not required for using a ModelChoiceField
thanks everyone for the help

Resources