How to set initial value for read only field - django-1.6

I have a django application which is using django.contrib.admin for administrative tasks.
For one model I now need to add a field which indicates which part of the code each row was created from. I am using readonly_fields to prevent this value from being changed through the administration interface.
A default value in this field will tell me that the row was either
created before the field was introduced
created by code which has not been updated to set the field
created through the administration interface
But I need better granularity than that. In particular I want to be able to distinguish between a row created by code which doesn't know about the field, and a row created through the administration interface.
Is there some way my ModelAdmin class can specify an initial value for a field mentioned in readonly_fields?

One way to do this is,
def get_form(self, request, caja=None, **kwargs):
self.form = YourModelForm
form = super(YourModelAdmin, self).get_form(request, caja, **kwargs)
form.base_fields['field'].initial = your_initial_data
return form

I found this solution, which appears to work:
class Admin(ModelAdmin):
readonly_fields = ('created_by',)
def save_form(self, request, form, change):
r = super(Admin, self).save_form(request, form, change)
if not change:
assert r.created_by == CREATED_BY_UNKNOWN
r.created_by = CREATED_BY_ADMIN
return r
CREATED_BY_UNKNOWN and CREATED_BY_ADMIN are values defined elsewhere in my code.

Related

Custom method on form submission with Umbraco Forms

What I'm trying to achieve is to customise what happens during the HttpPost/OnSubmit of a form created with Umbraco Forms, whilst still maintaining the default behaviour of the form and any subsequent workflow.
In my specific scenario, I need to be able to analyse the input of the form and based on that input I will send the user to a different "thank you" page, whilst also storing some elements of the originally submitted form in TempData.
I've tried the following:
I've tried to create a DocType controller (RenderMvcController), but this only allows you
to override the HttpGet, and not Post.
I cannot use a SurfaceController as I lose the functionality of the
module, Umbraco Forms.
I've tried to use a custom workflow, but this runs asynchronous to
the user's journey and I cannot change their experience.
There isn't much useful documentation available for this at all and I'm finding this task more difficult than I expected it to be.
In order to add a custom procedure after the submission of the form, and based on this procedure change the user journey you must do the following:
Create a new controller and inherit from UmbracoFormsController and override the OnFormHandled method
public class CustomUmbracoFormsController : UmbracoFormsController
{
protected override void OnFormHandled(Form form, FormViewModel model)
{
// Find the field in the form, then search for a matching value
var field = form.AllFields.FirstOrDefault(x => x.Alias == "deliveryOptions");
var fieldValue = model.FormState[field.Id.ToString()].GetValue(0).ToString();
// Add the value to the TempData
TempData["deliveryOptions"] = fieldValue;
}
}
The above is a basic implementation that doesn't account for NULL
Update the reference to UmbracoFormsController in /Views/Partials/Forms/Form.cshtml with your new controller from above.
...
#using (Html.BeginUmbracoForm<CustomUmbracoFormsController>("HandleForm"))
...
In the above example we analyse the form data and store some information in the TempData, we can set the form to redirect to a generic thank you page in which we can analyse the values in the TempData and change the view the user sees.
Also, if you are making changes to the Form values and what these to be updated, you'll need the Record Guid, which you can retrieve from TempData["Forms_Current_Record_id"] in conjunction with a new RecordStore object.

One form input to set two database values

I have a form which when submitted creates a new record in a database. I have two values in the database, value_1 & value_2. In the form there is an input field for value_1 which is a dropdown value of yes and no. When the form is submitted I wish to have value_1 and value_2 set to the value selected in the input field for value_1. So if dropdown for value_1 is set to yes then value_2 is also set to yes.
I am currently using the following but believe there must be a more elegant solution:
params[:person][:free] = params[:person][:trial]
#person = Person.new(params[:person])
#person.update_attribute(:free, params[:person][:free])
First you should think about what you really want. What is your logic.
Do you want value_2 always equal to value_1? I hope not, because in this case u absolutely no need a second column in your database.
Do you want value_2 equal to value_1 only the creation of a new record but allow it to be edited after that? In this case you should put the logic in your model with a callback :
In your model add :
before_create :set_value_2
private
def set_value_2
self.value_2 = value_1
end
The private statement is because you don't want anybody to access the method outside the model itself.

django admin inlines reordering read only fields

I am using tabular inlines in the django admin and have specified two fields to be read only. However django has now moved these to the very end of the inline (on the far right) There are a large number of fields, how can I move these 2 fields back to their original position (2nd, 3rd after pk) without having to specify the order of every field with fields=?
Use the get_fields() method of the ModelAdmin class:
#admin.register(Vintner)
class VintnerAdmin(admin.ModelAdmin):
exclude = ['field1', 'field2']
def get_fields(self, request, obj=None):
fields = super().get_fields(request, obj)
fields = fields[-2:] + fields[:-2] # or something more robust
return fields

How to Save page as Draft

I Had created a detailed form in Django having some mandatory fields .I want to save page as Draft option without exception if mandatory fields are not set that time. How can I do it?
First set required=False for the fields that don't have to be set if you save as a draft. Then, to your form, add a field like 'save_as_draft' which is a boolean. Now you need a method to validate these fields depending on the state of save_as_draft field (whether user checked this field or not). You can use such a method:
def is_provided(self, field):
value = self.cleaned_data.get(field, None)
if value == None or value == '':
self._errors[field] = ErrorList([u'This field is required.'])
if field in self.cleaned_data:
del self.cleaned_data[field]
Add this method to your form and use it in form's clean method to validate your fields. This would look like this:
def clean(self):
draft = self.cleaned_data.get('save_as_draft', False)
if not draft:
# User doesn't save a draft so we need to check if required fields are provided
req_fields = ['field1', 'field2', 'field3']
for f in req_field:
self.is_provided(f)
return self.cleaned_data
If user prefer save_as_draft button instead of checkbox, then you would need to modify your view and pass some parameter to your form's constructor depending on whether user clicked save_as_draft button or just save button. In Form constructor save this state aa self.save_as_draft and use this in Form.clean method to check if you are saving draft or not.
Greetings,
Lukasz

Add empty value to a DropDownList in ASP.net MVC

I'm building a data entry interface and have successfully bound the columns that have reference tables for their data using DropDownList so the user selects from the pre-configured values.
My problem now is that I don't want the first value to be selected by default, I need to force the user to select a value from the list to avoid errors where they didn't pick that field and by default a value was assigned.
Is there a more elegant way of doing this than to add code to include an empty value at the top of the list after I get it from the database and before i pass it to the SelectList constructor in my controller class?
The Html helper function takes a 'first empty value' parameter as the third argument.
<%=Html.DropDownList("name",dataSource,"-please select item-")%>
You can also use this way:
dropdownlist.DataTextField = ds.Tables[0].Columns[0].Caption;
dropdownlist.DataValueField = ds.Tables[0].Columns[1].Caption;
dropdownlist.DataSource = ds;
dropdownlist.DataBind();
dropdownlist.Items.Insert(0, new ListItem("Select ...", string.Empty));

Resources