SQLFORM.factory dropdownlist not mandatory - python

I have a custom form which I have designed using SQLForm.factory. I have created a dropdownlist in it as given below:
Field('method',requires=IS_IN_SET([(1,'Method1'),(2,'Method2'),(3,'Method3')],zero='Select'))
When I do not select any options from it it shows error as 'value not allowed'. I do not want it to be a mandatory field. I tried to set required argument of Field class's init method to False but it did not work. Please let me know how do I achieve that?

requires=IS_EMPTY_OR(IS_IN_SET(
[(1,'Method1'), (2,'Method2'), (3,'Method3')], zero='Select'))
Note, the required argument to Field() is enforced by the DAL upon inserts and results in an exception being thrown upon failure. The requires attribute includes a list of one or more validators that are processed during a SQLFORM submission -- violations of validators result in errors being displayed on the form, not Python exceptions.

Related

How to define a default ForeignKey object in django using get_or_create?

I have two models which I want to relate: User and Group.
Each user belongs to a group. I've tried to create a default user by using in get_or_create():
group = models.ForeignKey(Group.objects.get_or_create(name="Free")[0])
But it raises the following error:
(fields.E300) Field defines a relation with model 'Group', which is either not installed, or is abstract.
What can I do to fix this issue?
Each user must have a non-null group value. So I've read about this get_or_create() method. But I've also seen that it can return more than one object... and I don't want it to happen. I thought about creating a unique name parameter but is there a better solution for it?
Can you help me, please? I appreciate your help.
A more comprehensive answer can be found here: How to set a Django model field's default value to a function call / callable (e.g., a date relative to the time of model object creation)
You need to specifify the related Model and set the default.
class User(models.Model):
def default_group(self):
return Group.objects.get_or_create(name="Free")[0]
group = models.ForeignKey('app_name.Group', default=default_group)
Your default value would be evaluated at model definition time, but Django allows you to provide a callable as default, which is called for each instance creation.
To explain the error - code that is not inside a function, such as the line in your question, is executed as soon as your models.py file is loaded by Python. This happens early in the start-up of your Django process, when Django looks for a models.py file in each of the INSTALLED_APPS and imports it. The problem is that you don't know which other models have been imported yet. The error here is because the Group model (from django.auth.models) has not been imported yet, so it is as if it doesn't exist (yet).
Others have suggested you could put the Group.objects.get_or_create(name="Free")[0] in a function so that it is not executed immediately, Django will instead call the function only when it needs to know the value. At this point all the models in your project, and Django's own models, will have been imported and it will work.
Regarding the second part of your question... yes, any time you use get or get_or_create methods you need to query on a unique field otherwise you may get MultipleObjectsReturned exception.
In fact I think you should not use get_or_create for what you are trying to do here. Instead you should use an initial data fixture:
https://docs.djangoproject.com/en/1.9/howto/initial-data/
...to ensure that the default group already exists (and with a known primary key value) before you run your site.
That way you will know the unique pk of the default Group and you can do a get query:
def default_group():
return Group.objects.get(pk=1)
class YourModel(models.model):
group = models.ForeignKey(Group, default=default_group)

How do I redirect PloneFormGen to a page depending on the value in a select variable?

I am using PloneFormGen 1.7.12 in Plone 4.3.3. I have a large selection field that contains about 20 names. It is required. If the user picks one of the names, it should send them to a Plone Page template that has instructions for them. If it picks any other page, it should send the user an email with their form results and takes them to a thank you page.
I have tried doing this with a python script, but what I am doing doesn't work. The code in the script is:
REDIRECT = context.REQUEST.RESPONSE.redirect
URL=context.REQUEST.URL1 + '/'
FORM=context.REQUEST.form
school_name = context.REQUEST.form['school_name']
member = context.portal_membership.getAuthenticatedMember()
roles=member.getRolesInContext(context)
if school_name <> "Other-School not Listed":
return False
else:
return REDIRECT(URL + 'not_listed')
I put python:here.school_redirect() in the Custom Form Action override, but the URL displays:
python:here.school_redirect()
and the page displays "The address wasn't understood"
school_redirect is the id of the python script
not_listed is the id of the Plone page template
school_name is the id of the select field
Any suggestions are greatly appreciated.
Joe Bigler
The Custom Form Action is a simple StringField, no a TALES expression field.
This means you can add ./school_redirect to the Custom Form Action, but then you got other issues like returning False will not work, you need to redirect anyway. You also bypasses all validators and success handlers.
So imho another approach may be better:
1. Override the success handler
Custom Success Action Field on FormFolder. You may add a single expression or a python script, which returns the right value.
Field description:
Use this field in place of a thanks-page designation to determine final action after calling your action adapter (if you have one). You would usually use this for a custom success template or script. Leave empty if unneeded. Otherwise, specify as you would a CMFFormController action type and argument, complete with type of action to execute (e.g., "redirect_to" or "traverse_to") and a TALES expression. For example, "redirect_to:string:thanks-page" would redirect to 'thanks-page'.
Your ./school_redirect needs only small changes to fit for this solution. Do not redirect yourself, just return the right id (of a page template/view/etc.)
2. Do not trigger the mail adapter
For this purpose the Mail-Adapter provides a field called Execution Condition.
A TALES expression that will be evaluated to determine whether or not to execute this action. Leave empty if unneeded, and the action will be executed. Your expression should evaluate as a boolean; return True if you wish the action to execute. PLEASE NOTE: errors in the evaluation of this expression will cause an error on form display.
Add a script or expression, which evaluates if the email needs to be triggered or not.
You may reuse the ./school_redirect script to compose the expression: python: here.school_redirect() != 'not_listed'

How to get ticket fields in Trac

How can I get a list of ticket fields (like milestone, version, and all the custom fields) in Trac via Python?
In the Trac documentation I have found the TicketSystem class, but it is a component and I cannot instantiate it. So how do I access its methods if I need an instance for it?
Edit: I found out how I can access the default fields. E.g. for milestones, it is model.Milestone.select(self.env). Now the problem is, how can I access custom ticket fields? There must be a way to do it without having to access the database manually, since the method get_custom_fields() in the TicketSystem class exists.
Edit 2: I just found out that get_custom_fields() only returns the available fields, but not their values. What I want to do is get all available values of a specific custom field.
In the Trac documentation I have found the TicketSystem class, but it is a component and I cannot instantiate it.
You can obtain a reference to the Component, which is a singleton, with the statement ts = TicketSystem(self.env).
I just found out that get_custom_fields() only returns the available fields, but not their values. What I want to do is get all available values of a specific custom field.
That is incorrect. You can obtain the possible values of a ticket custom field with the statements:
fields = TicketSystem(self.env).get_custom_fields()
options = fields[idx].get('options', [])
where idx is the index of the field in the list for which you wish to retrieve the options. The list will only be non-empty if field['type'] is select or radio. See trac.ticket.api.TicketSystem.customfields.
I found out how I can access the default fields. E.g. for milestones, it is model.Milestone.select(self.env).
You should access all fields using TicketSystem(self.env).get_ticket_fields(). That statement will return all fields, including custom fields.

Django Rest Framework serializer field style argument

So I'm migrating some apps from DRF 2.4 to DRF 3.1. One of the changes that has been made is for serializer fields widget is no longer an valid argument. Instead we need to use style which according to the documentation expects a dict with key value pairs representing how the field is to be rendered. The example they give is:
# Use <input type="password"> for the input.
password = serializers.CharField(
style={'input_type': 'password'}
)
# Use a radio input instead of a select input.
color_channel = serializers.ChoiceField(
choices=['red', 'green', 'blue']
style = {'base_template': 'radio.html'}
}
This makes sense but what I am not seeing anywhere is where we find the valid values of base_template and input_type. For example if I wanted to make a field rendered as checkboxes how would I do that? What I am looking for is some documentation on what the API can accept and I'm not finding it anywhere. I feel kind of stupid asking this since it seems like it should be easy to find. Could anyone enlighten me? Am I just missing something obvious here? Any advice would be appreciated. Thanks!
I wanted to replace a select by a text input for a foreign key field, but likewise found only a few examples in the docs, e.g. http://www.django-rest-framework.org/topics/3.0-announcement/#the-style-keyword-argument-for-serializer-fields
Thanks to the debug toolbar, I could find out the default style for each serializer field and the actual location on disk: From there, I could look at the source directory to see the available values.
Use widget attribute do define form field type:
*Like THis *
code = serializers.CharField(widget=forms.Textarea())
You're probably using DRF v2.x.x, which doesn't support style argument in Field class

How to properly validate a MultipleChoiceField in a Django form

I have a MultipleChoiceField representing US states, and passing a GET request to my form like ?state=AL%2CAK results in the error:
Select a valid choice. AL,AK is not one of the available choices.
However, these values are definitely listed in the fields choices, as they're rendered in the form field correctly.
I've tried specifying a custom clean_state() method in my form, to convert the value to a list, but that has no effect. Printing the cleaned_data['state'] seems to show it's not even being called with the data from request.GET.
What's causing this error?
from django import forms
class MyForm(forms.Form):
state = forms.MultipleChoiceField(
required=False,
choices=[('AL','Alabama'),('AK','Alaska')],
)
MultipleChoiceFields don't pass all of the selected values in a list, they pass several different values for the same key instead.
In other words, if you select 'AL' and 'AK' your querystring should be ?state=AL&state=AK instead of ?state=AL%2CAK.
Without seeing your custom clean_state() method I can't tell you what's going wrong with it, but if the state field isn't valid because the querystring is wrong then 'state' won't be in cleaned_data (because cleaned_data only holds valid data).
Hopefully that helps. If you're still stuck try adding a few more details and I can try to be more specific.

Categories