Django - problem with writing to database - python

I have a problem, the urls form works but I can't see the records in url/admin, can I ask for help, thank you :D
SOF wants me to add more details otherwise it doesn't transfer, I don't know what more I can add, generally temapals and urls work.
class Note(models.Model):
"""..."""
notes = models.CharField(max_length=100, unique=True)
description = models.TextField()
class Meta:
verbose_name = "Note"
verbose_name_plural = "Notes"
def __str__(self):
return self.notes
class NoteView(View):
def get(self, request):
if request.method == 'POST':
textN = Note.objects.all().order_by('notes')
form = NoteAddForm(request.POST)
if form.is_valid():
form.save()
return redirect('Files/menu')
else:
textN = NoteAddForm()
return render(request, 'Files/note.html', {'textN': textN})
class NoteAddForm(forms.ModelForm):
"""New note add form"""
class Meta:
model = Note
fields = '__all__'
{% extends 'Files/base.html' %}
{% block title %}Notatnik{% endblock %}
<h2>Notatnik Dietetyka/ Zalecenia ręczne </h2>
{% block content %}
<form action="/send/" method="post">
{% csrf_token %}
{{ textN }}
<label>
<input type="text" class="btn btn-second btn-lg">
<button>Wyślij formularz</button>
</label>
</form>
<button type="button" class="btn btn-primary btn-lg">Powrót</button>
{% endblock %}

Within your NoteView class in views.py file is where the issue is.
I see you have an if statement checking for if request.method == 'POST' within the class-based view get(). The get() is equivalent to if request.method == 'GET'. Therefore, what you might want to do is to override the post() on the class instead. For example:
class NoteView(View):
template_name = 'Files/note.html'
# Use the get method to pass the form to the template
def get(self, request, *arg, **kwargs):
textN = NoteAddForm()
return render(request, self.template_name, {'textN': textN})
# Use the post method to handle the form submission
def post(self, request, *arg, **kwargs):
# textN = Note.objects.all().order_by('notes') -> Not sure why you have this here...
form = NoteAddForm(request.POST)
if form.is_valid():
form.save()
# if the path is... i.e: path('success/', SucessView.as_view(), name='success')
return redirect('success') # Redirect upon submission
else:
print(form.errors) # To see the field(s) preventing the form from being submitted
# Passing back the form to the template in the name 'textN'
return render(request, self.template_name, {'textN': form})
Ideally, that should fix the issue you're having.
Updates
On the form, what I'd suggest having is...
# Assuming that this view handles both the get and post request
<form method="POST"> # Therefore, removing the action attribute from the form
{% csrf_token %}
{{ textN }}
# You need to set the type as "submit", this will create a submit button to submit the form
<input type="submit" class="btn btn-second btn-lg" value="Submit">
</form>

Related

Django Register Form redirecting to same url

i am new to django i have created a user registration form but when i click on submit it does nothing and just goes to the same page i am not under standing what i did wrong here
views.py:
class RegisterPage(FormView):
template_name = "main/register.html"
form_class = RegisterForm
success_url = reverse_lazy('blog_list')
def form_valid(self, form):
user = form.save()
if user is not None:
login(self.request, user)
return super(RegisterPage, self).form_valid(form)
def get(self, *args, **kwargs):
if self.request.user.is_authenticated:
return redirect("blog_list")
return super(RegisterPage, self).get(*args, **kwargs)
forms.py:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
bio = forms.CharField(max_length=400, empty_value="Max Length 400")
image = forms.ImageField()
class Meta:
model = User
fields = ["username", "image", "password1", "password2", "bio"]
register.html:
{% extends "main/main.html" %}
{% block title %}Create an Account{% endblock %}
{% block content %}
<div class="form">
<h1>Register</h1>
<form method="post">
{% csrf_token %}
<label>{{form.username.label}}</label>
{{form.username}}
<br>
<label>{{form.password1.label}}</label>
{{form.password1}}
<br>
<label>{{form.password2.label}}</label>
{{form.password2}}
<br>
<label>{{form.image.label}}</label>
{{form.image}}
<br>
<label>{{form.bio.label}}</label>
{{form.bio}}
<br>
<input style="margin-top: 10px" class="button" type="submit" value="Register"/>
</form>
<p>Already Have An Account Login</p>
</div>
{% endblock content %}
in the views.py i have also tried form_class = UserCreationForm the built in django creation form but still the same result so what is wrong
you're posting the form back but you've only implemented a get method:
def get(self, *args, **kwargs):
if self.request.user.is_authenticated:
return redirect("blog_list")
return super(RegisterPage, self).get(*args, **kwargs)
And on the form html you're saying use POST <form method="post"> which is correct, and is the prefered way to send information you don't want to be sent in the URL. For example if you used <form method="get"> you code might work, but you'd also be sending the contents of the form in the url. Post sends it in the body, so if you use https on your server only you and the browser see it.
TO MAKE POST work you need to (add)
def post(self, *args, **kwargs):
#check the form do the redirect
As you didn't have an action on the form it defaults to submitting to the current url.
You need both get and post, as get will load the form post is how you're sending it back.

How can i use more different forms in the same Django template?

In my project, i have a template where i'm trying to put two forms for different use cases. I've never come across this problem before, so i don't really know where to go from here to use two forms in the same page.
At first i thought of creating another view to handle each form, but i think that this solution would create problems with the rendering of my templates, other than not being sustainable if i should have this problem again with another template.
After making some research, i found a solution but it works for class based views, but i'd like to avoid that since my view is already a function based view, and i would have to make a lot of changes in my code.
Would it be possible to solve this problem with a function based view? Every advice is appreciated
First field
class FirstForm(forms.ModelForm):
firstfield = forms.CharField()
secondfield = forms.CharField()
class Meta:
model = MyModel
fields = ("firstfield", "secondfield")
def save(self, commit=True):
send = super(FirstForm, self).save(commit=False)
if commit:
send.save()
return send**
Second Form
class SecondForm(forms.ModelForm):
firstfield = forms.FloatField()
secondfield = forms.Floatfield()
thirdfield = forms.CharField()
class Meta:
model = MyModelTwo
fields = ("firstfield", "secondfield", "thirdfield")
def save(self, commit=True):
send = super(SecondForm, self).save(commit=False)
if commit:
send.save()
return send
Template
<h3> First Form </h3>
<form method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form %}
<button type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>
</form>
<h3> Second Form </h3>
<form method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form %}
<button type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>
</form>
EDIT: my view:
def myview(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = FirstForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
send = form.save()
send.save()
messages.success(request, f"Success")
# if a GET (or any other method) we'll create a blank form
else:
form = FirstForm()
return render(request,
"main/mytemplate.html",
context={"form":form})
This answer is a bit general because you haven't included your view function. You can add each of these forms to your view's context. Something like this:
views.py
...
from .forms import FirstForm, SecondForm
...
def some_view(request):
context = {
'first_form': FirstForm(request.POST or None),
'second_form': SecondForm(request.POST or None)
}
return render(request, "app/some_template.html", context)

Can't add file in django 1.7

I cannot add a file in Django. When I click the "save" button, it does not save the database.
This is my view.py:
def add_product(request):
if request.method == "POST":
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.userprofile = request.user
post.save()
return redirect('kerajinan.views.add_product', pk=post.pk)
else:
form = PostForm()
return render(request, 'kerajinan/add_product.html', {'form': form})
add_product.html:
{% block content %}
<h1>New Product</h1>
<from method="POST" class="post-form" enctype="multiple/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</from>
{% endblock %}
forms.py:
class PostForm(forms.ModelForm):
class Meta:
model = Product
fields = ('category','title', 'price','image', 'description')
and urls.py:
url(r'^add_product/$', views.add_product, name='add_product'),
Can you help me solve my problem?
You need to change your enctype to: enctype="multipart/form-data"
Your current value (multiple/form-data), is not a valid method of encoding.
From the docs:
Note that request.FILES will only contain data if...the <form> that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.

formset for multiple form

ok i am following the formset. Pretty much i understand that formset is for multiple form.
so this example i just want take four values same time but the ouput in html have only one form is showing.
Shall i want to make extra filed like this <input id="your_name" type="text" name="your_name"> or django will do the rest or any other way to do that.?
models.py
class Article(models.Model):
title = models.CharField(max_length=100)
pub_date = models.DateField(auto_now_add=True)
forms.py
class ArticleForm(forms.Form):
title = forms.CharField()
#pub_date = forms.DateField()
ArticleFormSet = formset_factory(ArticleForm, extra=4, validate_max=True)
views.py
def book(request):
if request.method == 'POST':
formset = ArticleForm(request.POST)
if formset.is_valid():
new = Article()
new.title = request.POST.get('title', None)
#new.pub_date = request.POST.get('pub_date', None)
new.save()
return HttpResponseRedirect(reverse('firstapp.views.book'))
else:
formset = ArticleForm()
return render_to_response('get.html',{'formset': formset}, context_instance = RequestContext(request))
And the html look like this
<form method="post" action="">
{% csrf_token %}
{{ formset.management_form }}
<table>
{% for form in formset %}
{{ form }}
{% endfor %}
</table>
<input type="submit"/>
</form>
In your view you are binding formset to an ArticleForm, not to an ArticleFormSet. Also you are only creating one single Article from it, and you're not even using the form properly (ie: you're getting the title directly from request.POST instead of getting it from your form's cleaned_data). Your view code should look something like this (caveat: untested and possibly buggy code, but at least you'll get the picture).
def book(request):
if request.method == 'POST':
formset = ArticleFormSet(request.POST)
if formset.is_valid():
for data in formset.cleaned_data:
Article.objects.create(title=data['title'])
return HttpResponseRedirect(reverse('firstapp.views.book'))
else:
formset = ArticleFormSet()
return render_to_response('get.html',{'formset': formset},
context_instance = RequestContext(request))
As a last point, I strongly suggest you have a look at ModelForms.

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