Django forms with image fields validation - image

I have simple form with 2 fields: Name, Photo.
class MyForm(ModelForm):
class Meta:
model = My
class My(models.Model):
Name = models.models.CharField(max_length=512)
Photo = models.models.ImageField(upload_to=uploader)
I'am trying to validate and save this model. User chooses photo and doesn't enter name. Form does not pass validation. And user has error message. Then he enters name, but doesn't choose photo. And form doesn't validate again. But user has already chose photo.
I found article, where author explained this. But he wrote, that information out of date.
Tnx for help.

Docs covering validation: http://docs.djangoproject.com/en/dev/ref/forms/validation/
But it think it would be enough to set blank and null to false according to docs: http://docs.djangoproject.com/en/1.3/ref/models/fields/
UPDATE: blank and null diff coverage: http://www.b-list.org/weblog/2006/jun/28/django-tips-difference-between-blank-and-null/
But they come as default False... snap...
It means that all the validation has to be done as shown in http://docs.djangoproject.com/en/dev/ref/forms/validation/#using-validation-in-practice or in templates.
There is many ways to validate forms. You can use even javascript witch would allow post only when fields are valid.
Best probably would be do the validation according to this: http://docs.djangoproject.com/en/1.3/topics/forms/
UPDATE: It seems that its in some sort near duplicate of Resubmitting Image in ImageField after Validation Error in Django

You'll need to include enctype="multipart/form-data" in order to bind imagefield and filefield data to the form. Without that, those fields won't validate.
{% block page_content_body %}
<div class="row">
<div class="span12">
**<form enctype="multipart/form-data"** action="{% url 'deal_manager:deals_create' %}?place={{ place.id }}" method="post">
...

Related

Laravel Redirect as POST

Currently my users must get the visit form given by Route::get then fill it in to get back a result view given by Route::post. I need to create a shareable link such as /account/search/vrm/{vrm} where {vrm} is the VRM that is usually filled in on the form page. This VRM then needs to redirected to Route::post as post data. This needs to be done by my controller. How can I do this in my controller?
Routes:
// Shows form view
Route::get('/account/search', 'User\AccountController#getSearch')->name('account.search');
// Shows result view
Route::post('/account/search', 'User\AccountController#runSearch');
// Redirect to /account/search as POST
Route::get('/account/search/vrm/{vrm}', function($vrm) { ???????? });
POSTs cannot be redirected.
Your best bet is to have them land on a page that contains a form with <input type="hidden"> fields and some JavaScript that immediately re-submits it to the desired destination.
You can redirect to a controller action or call the controller directly, see the answer here:
In summary, setting the request method in the controller, or calling a controller's action.
Ps: I don't want to repeat the same thing.
For those who comes later:
If you are using blade templating engine for the views, you can add '#csrf' blade directive after the form starting tag to prevent this. This is done by laravel to prevent cross site reference attacks. By adding this directive, you can get around this.
return redirect()->route('YOUR_ROUTE',['PARAM'=>'VARIABLE'])

What's the proper way to have a default value only for CREATE view?

I would like to have a default value for my model attribute:
_form.blade.php code: {!! Form::text('attribute','Default Value') !!}
As _form.blade.php is shared for both create.blade.php and edit.blade.php, both views are always displaying the default value: Default Value.
What's the properly way to have a default value only for CREATE view?
So EDIT view should always display the value of the saved model.
It seems like a dumb question, but I'm a long time puzzling over this and I would like to know the properly way to do that.
I have some ideas, such as:
Do not use a shared file for create/edit (_form.blade.php) (I think it's not a good idea).
Set the default variable in the controller (also not good).
{!! Form::text('name', (isset($savedModel)) ? $savedModel->name : "your default value") !!}
I haven't tried a ternary inside a Form facade element, but it may work.
I believe what you want is this:
<input name="field" value="{{ old('field', isset($model->field) ? $model->field : '') }}"/>
Here's the breakdown:
If they edited/saved(first time) the form and the save failed, but was back()->withErrors(), this value will be used.
If they just invoked the "edit" view with no changes, the $model->field will be used.
If they are creating the model but have not attempted a save yet, no value will be used. ('')
This should cover all scenarios.
From my experience it's typically better not to share views between create/edit operations. You run into a lot of conditional logic that can be avoided and you get a cleaner user experience when displaying form errors and such.
As far as displaying a default value for the Create view, I use the old('attribute', 'Default Value') helper method to achieve this.

Directly access a put/update method on Laravel 5.1 without going into the edit view (MethodNotAllowedHttpException in RouteCollection.php error)

I wanted to disable employees from a button on my index.blade.php page. Currently, the options of disabling employees (setting the status column in the database to false) is either to have an edit.blade.php view and update the value there, which is pretty standard for any laravel app or to have a new view for example, changestatus.blade.php, with the proper routes offcourse and update the value there. I am using the second implementation and it's working perfectly.
What i wanted to implement is to have a button on the index page which will change the status of the employee without going to a edit.blade.php or changestatus.blade.php page.
What i have tried
I have created new routes and created a button to link to the changestatus function
Routes.php
Route::put('employees/{employee}/changestatus', 'EmployeesController#changestatus')->name('employees.changestatus');
Route::resource('employees', 'EmployeesController');
EmployeeController
public function changestatus($EmployeeID)
{
$employee = Employee::find($EmployeeID);
$employee->status = true;
$employee->Save();
}
On my view i created a button with the following link
{{ URL::route('employees.changestatus', $employee->EmployeeID) }}
When i click that link, i get the MethodNotAllowedHttpException in RouteCollection.php error.
I even tried to change the Route::put to Route::Patch, but it's the same thing.
Is it even possible to achieve what I'm trying to do? If so, how?
When you click on a hyperlink, the web browser submits a GET request. Your route has been defined as being a PUT so that's why you're getting an exception.
You could either change the route to a GET by defining it like this:
Route::get('employees/{employee}/changestatus', 'EmployeesController#changestatus')->name('employees.changestatus');
Which isn't very ReSTful since a GET request should really only be used for returning a resource rather than modifying it.
Or, you could modify the button so that it submits a form like this:
<form method="post" action="{{ route('employees.changestatus', $employee->EmployeeID) }}">
{{ method_field('PUT') }}
<button type="submit">Button Text</button>
</form>
Note that you can't simply set the form method to PUT since this method isn't generally supported by web browsers. Laravel supports method spoofing which you can read all about here:
http://laravel.com/docs/5.1/routing#form-method-spoofing

MVC3 Razor Ajax partial page validation

I have a wizard style page that I want to validate a page at a time. So before the user can move off the (partial) page I submit the inputs from the div for validation. Client side validation works OK but on some pages there are one or more fields I need to validate on the server. Yes I know about remote validation.
I can get the server side validation done without a problem. The issue I have is how do I display the errors on the correct fields? I can locate the fields in the div and find the span where the error message is suppose to go. But I just can't get the message to display.
I must be missing something when updating the field span. I would have thouht that there is a jQuery routine to add error information to a field. I need something similar to the controllers AddModuleError. So when I get return from my $.Post I can set error text on the appropriate fields.
Any suggestions?
A potential solution to your problem might be in this article "Client side validation after Ajax Partial View result in ASP.NET MVC 3"
Basically, once you get your html from the post you can invoke validation using jQuery.validator.unobtrusive.parse()
As per the example in the article;
$.post("YourAction", { data: <your form data> },
function(htmlContent){
$('#container').html(htmlContent);
jQuery.validator.unobtrusive.parse('#content')
}
Worth looking into
If you are using the included RemoteAttribute, or the version I linked to in my answer to your other remote validation question, then you should not have to worry about displaying the error, as both work with the ValidationMessage helpers to automatically display errors.
Have you added Html.ValidationMessage(...) or Html.ValidationMessageFor(...) for each field to be validated?

How to use SSL/https with non-menu items?

We have a site that needs to have several sections be secure. We have
our SSL certificate installed, and for the areas that are accessible
via menu item, it's no problem - we just use the SSL Enabled system
parameter in the menu item editor. But we have a few sections (i.e. a
shopping cart checkout screen) that are only accessible via a submit
button (they don't have their own URL, so to speak - they're just
submitted to themselves via the controller and the view changes based
on the form action.) Right now, the form action is set like this:
<form name="instantForm" action="/<?=$this->segment?>/" method="post" onsubmit="updateSubmitValue()">
where segment is passed via the view.html.php. The rendered form tag
looks like this:
<form id = "checkoutForm" name="checkoutForm" action="/checkout/" method="post" onsubmit="updateSubmit()">
When submitted, the controller grabs the value of a few submitted
fields and determines which view to display (logged in with saved
account info or anonymous transaction) and then displays the correct
form.
Here's a stripped-down version of the controller's display method:
if (JRequest::getVar('checkoutCodeSubmitBTN') != ""){
//user has clicked Checkout button; go to billing info page
JRequest::setVar('view','checkoutpay');
// JRequest::setVar('view','checkout_thankyou');
//reference view
$viewCode =& $this->getView('checkoutpay','html');
$viewCode->voucher =& $voucher;
} //close test for step 1 if
How can I make sure that the view that gets displayed gets switched
over to an https URL?
I've already posted this on the google joomla dev discussion group, and got a response telling me to use JRoute to generate a URL and use setRedirect instead of posting to the form, but then someone else responded that using JRoute produces a completely new request, so all your access to JRequest::getVar type stuff is gone. We need to be able to access the variables that are posted through the form, so that solution is out. Does anyone have any other ways of doing this? I'm pretty new to Joomla development and am not familiar with many of the objects and methods available.
I've heard from some people that JRoute would be better for this, but that only works if you know the URL you need; we have to build our URL dynamically based on the current request, so I used JURI.
In my view.html.php, I added this code:
$needSecure = $model->needSecure();
if($needSecure) {
$u =& JURI::getInstance( JURI::base() );
$u->setScheme( 'https' );
$tmpURL = $u->toString()."checkout";
}
else {
$tmpURL = "/checkout";
}
$this->assignRef("tmpURL", $tmpURL);
needSecure() is a function in my model that pulls a value from a database table and returns a boolean. So if needSecure returns true, we get the current request URI, set the first part to https, then append the bit that we're submitting to. If it returns false, we just set the bit to submit to.
In the default.php, we have this:
<form id = "checkoutForm" name="checkoutForm" action="<?=$this->tmpURL?>/" method="post" onsubmit="updateSubmit()">
If needSecure is true, the action renders to
<form id = "checkoutForm" name="checkoutForm" action="https://www.mysite.com/checkout" method="post" onsubmit="updateSubmit()">
otherwise it renders to
<form id = "checkoutForm" name="checkoutForm" action="/checkout" method="post" onsubmit="updateSubmit()">
It works perfectly, and because we're storing the boolean in a database, it means we don't ever have to change the code itself if we want to make a new form submission secure or insecure.

Resources