When i click on Share this Post in show_more.html , this error is raised.
show_more.html
<p>
Share This Post
</p>
urls.py
path('<int:post_id>/share/',views.post_share,name='post_share'),
views.py
def post_share(request, post_id):
post = get_object_or_404(Post,pk=post_id, status='published')
if request.method == 'POST':
form = EmailPost(request.POST)
if form.is_valid():
else:
form = EmailPost()
return render(request, 'mains/post_share.html', {'post':post,'form':form})
forms.py
class EmailPost(forms.Form):
name_subject = forms.CharField(max_length=400)
email = forms.EmailField()
description = forms.CharField(required=False,widget=forms.Textarea)
This error generally occurs when the url reference in your html file does not match with any paths in your urls.py file.
In urls.py:
path('post_share/<int:post_id>',views.post_share,name='post_share'),
This should solve your current problem. It is a good practice to show your error stack trace when asking questions.
Related
Hello is there a way to get 'value' attribute from HTML template into views.py and use it there??
HTML:
<form class="card__delete" method="POST"> {% csrf_token %}
<button value="{{item.id}}" class="card__delete__button" name="delete" type="submit">✘</button>
</form>
views.py
class TodoView(UserPassesTestMixin, CreateView):
model = Item
template_name = 'home/todo.html'
form_class = ItemCreationForm
def test_func(self):
return self.request.user.username in self.request.path
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['card'] = Card.objects.get(user=self.request.user, pk=self.kwargs.get('pk'))
return context
def post(self, request, pk, username):
if 'delete' in self.request.POST:
Item.objects.get(id=pk).delete()
print('deleted')
return redirect('home-page')
The value is in request.POST, so you should be able to access it with
value = self.request.POST.get('delete', None)
Take care to validate that value before using the id of an object to do anything catastrophic to it (such as .delete()). It's not being validated through a form, and a random hacker on the internet might try posting back random numbers which might be the id of other objects
Added after reading comment:
Data pulled out of request.POST is raw data. I don't think CSRF token can protect against a person who uses inspect object in his browser and changes the value of that button before clicking it. I may be wrong.
Anyway, if you can check the value using a queryset of the object type with a filter for objects that this user is permitted to delete, then do. For example,
value = request.POST.get("delete", None)
if value:
obj = Card.objects.filter(
user=self.request.user ).get( pk=value)
# will raise CardDoesNotExist if value isn't one of user's objects,
# because it's been filtered out
obj.delete()
I am trying to raise validation error for the entry field in the forms.py
My models.py
class StudBackground(models.Model):
stud_name=models.CharField(max_length=200)
class Student(models.Model):
name=models.CharField(max_length=200)
My forms.py
class StudentForm(forms.ModelForm):
name = forms.CharField(max_length=150, label='',widget= forms.TextInput)
class Meta:
model = Student
fields = ['name',]
where i tried to apply clean method :
def clean_student(self,*args,**kwargs):
name=self.cleaned_data.get("name")
if not studBackground.stud_name in name:
raise forms.ValidationError ( "It is a not valid student")
else: return name
I tried to incorporate stud_name from the StudBackground model to the form but it does not work it raises following error when i try to type student name that is not in DB:
Profiles matching query does not exist
however it supposed to return near the name field "It is a not valid student"
How to make it work? What is the wrong with the code?
You can try like this:
def clean_student(self):
name=self.cleaned_data.get("name")
if not StudBackground.objects.filter(stud_name=name).exists():
raise forms.ValidationError("It is a not valid student")
return name
I am using filter(...) function from queryset to check if a name exists in StudBackground. I am also running exists() to check if entry exists in DB.
Update
I think your indentations are not correct for the view. But, you can try like this:
def home(request):
form = StudentForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
instance = form.save()
name = instance.name
class_background=StudBackground.objects.get(stud_name=name)
context={'back':class_background}
return render(request, 'class10/background.html', context)
# Now let us handle if request type is GET or the form is not validated for some reason
# Sending the form instance to template where student form is rendered. If form is not validated, then form.errors should render the errors.
# How to show form error: https://docs.djangoproject.com/en/3.0/topics/forms/#rendering-form-error-messages
return render(request, 'your_student_form_template.html', context={'form':form})
This is an excerpt of my view.py
def routineInput(request):
if request.method == 'POST':
today = datetime.now
form = CreateRoutine(request.POST)
if form.is_valid():
return HttpResponseRedirect('/todo/saved/')
else:
form = CreateRoutine()
return render(request, 'todo/croutine.html', {'form': form})
So the idea is that I have a simple input form where I put a name into it and it should push this name into a table in my database. My code is coming thorough and it shows my /todo/saved page but my POST request doesn't seem to get sent to my table or my table is rejecting it or something.
My model.py class:
class Todolist(models.Model):
name = models.TextField()
created_at = models.DateTimeField(default = datetime.now, blank = True)
updated_at = models.DateTimeField(default = datetime.now, blank = True)
You are not saving your form data.
do
if form.is_valid():
form.save()
return HttpResponseRedirect('/todo/saved/')
I wrote a login page, of course it contains a form. Then I wrote my LoginView use class like this:
class LoginView(View):
def get(self, request):
return render(request, "login.html")
def post(self, request):
login_form = LoginForm(request.POST)
if login_form.is_valid():
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return render(request, 'index.html')
else:
return render(request, 'login.html', {'msg':'账号未激活!'}, {'login_form':login_form})
else:
return render(request, 'login.html', {'msg':'用户名不存在!'}, {'login_form':login_form})
else:
return render(request, 'login.html', {'msg':'用户名或密码错误!'}, {'login_form':login_form})
Ignore the Chinese you may not know.
I tried to input wrong username and password, it should return the same page with error message to allow me to input again, but...
It return a page contains all html code, seems like the browser didn't compile the codes?
If there's a mistake I made in LoginView?
You need to access the form.cleaned_data not request.POST,
username = login_form.cleaned_data['username']
password = login_form.cleaned_data['password']
I have a text area in a django based website that displays the content of a database field.
I'd like to be able to edit this field and submit it to a function which updates the field in the database.
I know how I can call a function in a views.py which then send back the result of the query using render_to_response to a new webpage.
So in summary, how do I adress a function in a django/python script using a html form without the need to refer to another url?
It's usually recommended to use Post/Redirect/Get pattern, for example:
def myview(request, **kwargs):
if request.POST:
# validate the post data
if valid:
# save and redirect to another url
return HttpResponseRedirect(...)
else:
# render the view with partial data/error message
if request.GET:
# render the view
return render_to_response(...)
Use AJAX:
1) Create a view to handle form submission:
def my_ajax_form_submission_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# save data or whatever other action you want to take
resp = {'success': True}
else:
resp = {'success': False}
return HttpResponse(simplejson.dumps(resp), mimetype='application/json')
else:
return HttpResponseBadRequest()
Then, tie the view into your urlpatterns
2) Submit form via AJAX (uses jQuery):
$('#my-form-id').submit(function(){
var $form = $(this);
$.post('/url/to/ajax/view/', $form.serialize(), function(data, jqXHR){
if (data.success) {
alert('Form submitted!');
} else {
alert('Form not valid');
}
});
return false;
});
That's the basics. You can and should provide more detailed return responses, error handling, form validation/checking, etc.
This is the standard views code pattern that I've been using.
def payment_details(request, obj_id):
yourobj = get_object_or_404(Obj, pk=obj_id)
form = TheForm(instance=yourobj)
if request.method == 'POST':
form = TheForm(request.POST, instance=yourobj)
if form.is_valid():
yourobj = form.save()
messages.success(request, 'Yourobj is saved!')
url = reverse('SOMEURL')
return redirect(url)
template = 'SOMETEMPLATE'
template_vars = {'TEMPLATEVARS': TEMPLATEVARS}
return render(request, template, template_vars)
Having watched the Advanced Forms talk at DjangoCon, one could re-write the above view like this:
def payment_details(request, obj_id):
yourobj = get_object_or_404(Obj, pk=obj_id)
form = TheForm(request.POST or NONE, instance=yourobj)
if request.method == 'POST' and form.is_valid():
yourobj = form.save()
messages.success(request, 'Yourobj is saved!')
url = reverse('SOMEURL')
return redirect(url)
template = 'SOMETEMPLATE'
template_vars = {'TEMPLATEVARS': TEMPLATEVARS}
return render(request, template, template_vars)