class ValidateSourceForm(forms.Form): source_type = forms.CharField(max_length=1, required=True, widget=forms.HiddenInput()) source_url = forms.URLField(label=_('Source URL'), required=True)
class ExperimentOverviewForm(UniqueNameSlugFormMixin, ChangeLogMixin, forms.ModelForm): type = forms.ChoiceField( label="Type", choices=Experiment.TYPE_CHOICES, help_text=Experiment.TYPE_HELP_TEXT, ) owner = forms.ModelChoiceField( required=True, label="Experiment Owner", help_text=Experiment.OWNER_HELP_TEXT, queryset=get_user_model().objects.all().order_by("email"), # This one forces the <select> widget to not include a blank # option which would otherwise be included because the model field # is nullable. empty_label=None, ) engineering_owner = forms.CharField( required=False, label="Engineering Owner", help_text=Experiment.ENGINEERING_OWNER_HELP_TEXT, ) name = forms.CharField(label="Name", help_text=Experiment.NAME_HELP_TEXT) slug = forms.CharField(required=False, widget=forms.HiddenInput()) short_description = forms.CharField( label="Short Description", help_text=Experiment.SHORT_DESCRIPTION_HELP_TEXT, widget=forms.Textarea(attrs={"rows": 3}), ) public_name = forms.CharField( label="Public Name", required=False, help_text=Experiment.PUBLIC_NAME_HELP_TEXT, ) public_description = forms.CharField( label="Public Description", required=False, help_text=Experiment.PUBLIC_DESCRIPTION_HELP_TEXT, widget=forms.Textarea(attrs={"rows": 3}), ) data_science_bugzilla_url = BugzillaURLField( label="Data Science Bugzilla URL", help_text=Experiment.DATA_SCIENCE_BUGZILLA_HELP_TEXT, ) feature_bugzilla_url = BugzillaURLField( required=False, label="Feature Bugzilla URL", help_text=Experiment.FEATURE_BUGZILLA_HELP_TEXT, ) related_work = forms.CharField( required=False, label="Related Work URLs", help_text=Experiment.RELATED_WORK_HELP_TEXT, widget=forms.Textarea(attrs={"rows": 3}), ) proposed_start_date = forms.DateField( required=False, label="Proposed Start Date", help_text=Experiment.PROPOSED_START_DATE_HELP_TEXT, widget=forms.DateInput(attrs={ "type": "date", "class": "form-control" }), ) proposed_duration = forms.IntegerField( required=False, min_value=1, label="Proposed Experiment Duration (days)", help_text=Experiment.PROPOSED_DURATION_HELP_TEXT, widget=forms.NumberInput(attrs={"class": "form-control"}), ) proposed_enrollment = forms.IntegerField( required=False, min_value=1, label="Proposed Enrollment Duration (days)", help_text=Experiment.PROPOSED_ENROLLMENT_HELP_TEXT, widget=forms.NumberInput(attrs={"class": "form-control"}), ) class Meta: model = Experiment fields = [ "type", "owner", "engineering_owner", "name", "slug", "short_description", "public_name", "public_description", "data_science_bugzilla_url", "feature_bugzilla_url", "related_work", "proposed_start_date", "proposed_duration", "proposed_enrollment", ] def clean_proposed_start_date(self): start_date = self.cleaned_data["proposed_start_date"] if start_date and start_date < timezone.now().date(): raise forms.ValidationError( ("The experiment start date must " "be no earlier than the current date.")) return start_date def clean(self): cleaned_data = super().clean() # enrollment may be None enrollment = cleaned_data.get("proposed_enrollment", None) duration = cleaned_data.get("proposed_duration", None) if (enrollment and duration) and enrollment > duration: msg = ("Enrollment duration is optional, but if set, " "must be lower than the experiment duration. " "If enrollment duration is not specified - users " "are enrolled for the entire experiment.") self._errors["proposed_enrollment"] = [msg] return cleaned_data
class ReturnURLForm(forms.Form): """ Provides a hidden return URL field to control where the user is directed after the form is submitted. """ return_url = forms.CharField(required=False, widget=forms.HiddenInput())
class SearchForm(forms.Form): """ Supports persistence of searches (stores search in the session). Requires not only the GET parameters but the request object itself to work correctly. Usage example:: class AddressManager(SearchManager): search_fields = ('first_name', 'last_name', 'address', 'email', 'city', 'zip_code', 'created_by__email') class Address(models.Model): ... objects = AddressManager() class AddressSearchForm(SearchForm): orderings = { '': ('last_name', 'first_name'), # Default 'dob': 'dob', # Sort by date of birth 'random': lambda queryset: queryset.order_by('?'), } is_person = forms.NullBooleanField() def addresses(request): search_form = AddressSearchForm(request.GET, request=request) queryset = search_form.queryset(Address) ctx = { 'addresses': queryset, 'search_form': search_form, } return render(request, 'addresses.html', ctx) .. warning:: All fields in the form need to have ``required=False`` set. Otherwise, form validation would already fail on the first visit on the list page (which would kind of defeat the purpose of a search form). Template code:: <form method="get" action="."> <input type="hidden" name="s" value="1"> <!-- SearchForm search --> <table> {{ search_form }} </table> <button type="submit">Search</button> </form> {% for address in addresses %} ... {% endfor %} """ #: Fields which are always excluded from automatic filtering #: in ``apply_filters`` always_exclude = ("s", "query", "o") #: Default field values - used if not overridden by the user default = {} #: Ordering specification orderings = {} #: Quick rules, a list of (regex, mapper) tuples quick_rules = [] #: Search form active? s = forms.CharField(required=False, widget=forms.HiddenInput(), initial="1") #: Current ordering o = forms.CharField(required=False, widget=forms.HiddenInput()) #: Full text search query query = forms.CharField( label=_("Query"), required=False, widget=forms.TextInput(attrs={"placeholder": _("Query")}), ) def __init__(self, data, *args, **kwargs): # Are the results filtered in any way? self.filtered = True # Is a persisted search active? self.persistency = False request = kwargs.pop("request") self.original_data = data super(SearchForm, self).__init__( self.prepare_data(data, request), *args, **kwargs ) self.persist(request) self.post_init(request) def prepare_data(self, data, request): """ Fill in default values from ``default`` if they aren't provided by the user. """ if not self.default: return data data = data.copy() for key, value in self.default.items(): if key not in data: if hasattr(value, "__call__"): value = value(request) if hasattr(value, "__iter__"): data.setlist(key, value) else: data[key] = value return data def post_init(self, request): """ Hook for customizations. """ pass def persist(self, request): """ Persist the search in the session, or load saved search if user isn't searching right now. """ session_key = "sf_%s.%s" % (self.__class__.__module__, self.__class__.__name__) if "clear" in request.GET or "n" in request.GET: if session_key in request.session: del request.session[session_key] if self.original_data and ( set(self.original_data.keys()) & set(self.fields.keys()) ): data = self.data.copy() if "s" in data: del data["s"] request.session[session_key] = data.urlencode() elif request.method == "GET" and "s" not in request.GET: # try to get saved search from session if session_key in request.session: session_data = force_bytes(request.session[session_key]) self.data = QueryDict(session_data, encoding="utf-8") self.persistency = True else: self.filtered = False elif request.method == "POST" and "s" not in request.POST: # It wasn't the search form which was POSTed, hopefully :-) self.filtered = False def searching(self): """ Returns ``searching`` for use as CSS class if results are filtered by this search form in any way. """ if self.persistency or self.safe_cleaned_data.get("s"): return "searching" return "" @property def safe_cleaned_data(self): """ Safely return a dictionary of values, even if search form isn't valid. """ self.is_valid() try: return self.cleaned_data.copy() except AttributeError: return {} def fields_iterator(self): """ Yield all additional search fields. """ skip = ("query", "s", "o") for field in self: if field.name not in skip: yield field def apply_filters(self, queryset, data, exclude=()): """ Automatically apply filters Uses form field names for ``filter()`` argument construction. """ exclude = list(exclude) + list(self.always_exclude) for field in self.fields.keys(): if field in exclude: continue value = data.get(field) if ( value and hasattr(value, "__iter__") and not isinstance(value, six.string_types) ): queryset = queryset.filter(**{"%s__in" % field: value}) elif value or value is False: queryset = queryset.filter(**{field: value}) if self.quick_rules: quick_only = set(data.keys()) - set(self.fields.keys()) for field in quick_only: if field in exclude: continue if field.endswith("_") and ( field[:-1] in quick_only or field[:-1] in self.fields ): # Either ``quick.model_mapper`` wanted to trick us and # added the model instance, too, or the quick mechanism # filled an existing form field which means that the # attribute has already been handled above. continue value = data.get(field) if value is not None: queryset = queryset.filter(**{field: value}) return queryset def apply_ordering(self, queryset, ordering=None): """ Applies ordering if the value in ``o`` matches a key in ``self.orderings``. The ordering may also be reversed, in which case the ``o`` value should be prefixed with a minus sign. """ if ordering is None: return queryset if ordering and ordering[0] == "-": order_by, desc = ordering[1:], True else: order_by, desc = ordering, False if order_by not in self.orderings: # Ignore ordering request if unknown return queryset order_by = self.orderings[order_by] if hasattr(order_by, "__call__"): queryset = order_by(queryset) elif isinstance(order_by, (list, tuple)): queryset = queryset.order_by(*order_by) else: queryset = queryset.order_by(order_by) if desc: return queryset.reverse() return queryset def query_data(self): """ Return a fulltext query and structured data which can be converted into simple filter() calls """ if not hasattr(self, "_query_data_cache"): data = self.safe_cleaned_data if self.quick_rules: data, query = quick.parse_quickadd(data.get("query"), self.quick_rules) query = " ".join(query) # Data in form fields overrides any quick specifications for k, v in self.safe_cleaned_data.items(): if v is not None: data[k] = v else: query = data.get("query") self._query_data_cache = query, data return self._query_data_cache def queryset(self, model): """ Return the result of the search """ query, data = self.query_data() queryset = model.objects.search(query) queryset = self.apply_filters(queryset, data) return self.apply_ordering(queryset, data.get("o"))
class ContributionForm(forms.ModelForm): contributor = UserModelChoiceField( queryset=UserProfile.objects.exclude_inactive_users()) responsibility = forms.ChoiceField( widget=forms.RadioSelect(), choices=Contribution.RESPONSIBILITY_CHOICES) evaluation = forms.ModelChoiceField(Evaluation.objects.all(), disabled=True, required=False, widget=forms.HiddenInput()) questionnaires = forms.ModelMultipleChoiceField( Questionnaire.objects.contributor_questionnaires().filter( obsolete=False), required=False, widget=CheckboxSelectMultiple, label=_("Questionnaires")) does_not_contribute = forms.BooleanField( required=False, label=_("Does not contribute to evaluation")) class Meta: model = Contribution fields = ('evaluation', 'contributor', 'questionnaires', 'order', 'responsibility', 'textanswer_visibility', 'label') widgets = { 'order': forms.HiddenInput(), 'textanswer_visibility': forms.RadioSelect( choices=Contribution.TEXTANSWER_VISIBILITY_CHOICES) } def __init__(self, *args, evaluation=None, **kwargs): self.evaluation = evaluation # work around https://code.djangoproject.com/ticket/25880 if self.evaluation is None: assert 'instance' in kwargs self.evaluation = kwargs['instance'].evaluation super().__init__(*args, **kwargs) if self.instance.can_edit: self.fields['responsibility'].initial = Contribution.IS_EDITOR else: self.fields['responsibility'].initial = Contribution.IS_CONTRIBUTOR if self.instance.contributor: self.fields['contributor'].queryset |= UserProfile.objects.filter( pk=self.instance.contributor.pk) self.fields[ 'questionnaires'].queryset = Questionnaire.objects.contributor_questionnaires( ).filter( Q(obsolete=False) | Q(contributions__evaluation=self.evaluation)).distinct() if self.instance.pk: self.fields[ 'does_not_contribute'].initial = not self.instance.questionnaires.exists( ) if self.evaluation.pk and not self.evaluation.can_be_edited_by_manager: # form is used as read-only evaluation view disable_all_fields(self) def clean(self): if not self.cleaned_data.get( 'does_not_contribute') and not self.cleaned_data.get( 'questionnaires'): self.add_error( 'does_not_contribute', _("Select either this option or at least one questionnaire!")) def save(self, *args, **kwargs): responsibility = self.cleaned_data['responsibility'] is_editor = responsibility == Contribution.IS_EDITOR self.instance.can_edit = is_editor return super().save(*args, **kwargs)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["order"].widget = forms.HiddenInput()
class VariationManagerForm(forms.Form): dirty = forms.CharField(widget=forms.HiddenInput(), required=False) def __init__(self, *args, **kwargs): self.optionkeys = [] self.variationkeys = [] self.existing = {} self.optiondict = {} self.edit_urls = {} self.namedict = {} self.skudict = {} self.slugdict = {} self.product = kwargs.pop('product', None) super(VariationManagerForm, self).__init__(*args, **kwargs) if self.product: configurableproduct = self.product.configurableproduct; for grp in configurableproduct.option_group.all(): optchoices = [("%i_%i" % (opt.option_group.id, opt.id), opt.name) for opt in grp.option_set.all()] kw = { 'label' : grp.name, 'widget' : forms.CheckboxSelectMultiple(), 'required' : False, 'choices' : optchoices, } fld = forms.MultipleChoiceField(**kw) key = 'optiongroup__%s' % grp.id self.fields[key] = fld self.optionkeys.append(key) self.optiondict[grp.id] = [] configurableproduct.setup_variation_cache() for opts in configurableproduct.get_all_options(): variation = configurableproduct.get_product_from_options(opts) optnames = [opt.value for opt in opts] kw = { 'initial' : None, 'label' : " ".join(optnames), 'required' : False } opt_str = '__'.join(["%i_%i" % (opt.option_group.id, opt.id) for opt in opts]) key = "pv__%s" % opt_str if variation: basename = variation.name sku = variation.sku slug = variation.slug kw['initial'] = 'add' self.existing[key] = True self.edit_urls[key] = urlresolvers.reverse('admin:product_product_change', args=(variation.id,)) else: basename = u'%s (%s)' % (self.product.name, u'/'.join(optnames)) slug = slugify(u'%s_%s' % (self.product.slug, u'_'.join(optnames))) sku = "" pv = forms.BooleanField(**kw) self.fields[key] = pv for opt in opts: self.optiondict[opt.option_group.id].append(key) self.variationkeys.append(key) # Name Field nv = forms.CharField(initial=basename) namekey = "name__%s" % opt_str self.fields[namekey] = nv self.namedict[key] = namekey # SKU Field sv = forms.CharField(initial=sku, required=False) skukey = "sku__%s" % opt_str self.fields[skukey] = sv self.skudict[key] = skukey # Slug Field sf = forms.CharField(initial=slug) slugkey = "slug__%s" % opt_str self.fields[slugkey] = sf self.slugdict[key] = slugkey def _save(self, request): self.full_clean() data = self.cleaned_data optiondict = _get_optiondict() #dirty is a comma delimited list of groupid__optionid strings dirty = self.cleaned_data['dirty'].split(',') if dirty: for key in dirty: # this is the keep/create checkbox field try: keep = data["pv__" + key] opts = _get_options_for_key(key, optiondict) if opts: if keep: self._create_variation(opts, key, data, request) else: self._delete_variation(opts, request) except KeyError: pass save = transaction.commit_on_success(_save) def _create_variation(self, opts, key, data, request): namekey = "name__" + key nameval = data[namekey] skukey = "sku__" + key skuval = data[skukey] slugkey = "slug__" + key slugval = data[slugkey] log.debug("Got name=%s, sku=%s, slug=%s", nameval, skuval, slugval) v = self.product.configurableproduct.create_variation( opts, name=nameval, sku=skuval, slug=slugval) log.info('Updated variation %s', v) messages.add_message(request, messages.INFO, 'Created %s' % v) return v def _delete_variation(self, opts, request): variation = self.product.configurableproduct.get_product_from_options(opts) if variation: log.info("Deleting variation for [%s] %s", self.product.slug, opts) messages.add_message(request, messages.INFO, 'Deleted %s' % variation) variation.delete()
class AgentNameForm(forms.Form): agent_name = forms.CharField(widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): super(AgentNameForm, self).__init__(*args, **kwargs) self.fields['agent_name'].widget.attrs['readonly'] = True
def __init__(self, user, *args, **kwargs): self.user = user super(CreateVideoUrlForm, self).__init__(*args, **kwargs) self.fields['video'].widget = forms.HiddenInput()
class ActivityCreationForm(forms.ModelForm): error_messages = { "should_be_int": u"应当填写整数", "invalid_activity_type": u"活动类型无效", "wrong_prov_city": u"省份/城市数据格式错误", "start_time_error": u"活动不能在过去开始", "end_time_error": u"活动不能在开始之前结束", "last_length_error": u'持续时间太长' } day = forms.CharField(widget=forms.NumberInput(attrs={ "class": "content time" }), required=False, initial=0) hour = forms.CharField(widget=forms.NumberInput(attrs={ "class": "content time" }), required=False, initial=0) minute = forms.CharField(widget=forms.NumberInput(attrs={ "class": "content time" }), required=False, initial=0) activity_type = forms.CharField(max_length=10, widget=forms.HiddenInput(attrs={ "id": "action-type", "name": "action-type" })) poster = forms.ImageField(widget=forms.FileInput(attrs={ "id": "poster", "name": "poster" }), required=False) present = forms.CharField(required=False) reward = forms.IntegerField(widget=forms.NumberInput(attrs={ "class": "content", "placeholder": u"请输入奖励金额" }), required=False, initial=0) def __init__(self, user=None, *args, **kwargs): super(ActivityCreationForm, self).__init__(*args, **kwargs) self.user = user def clean_activity_type(self): activity_type = self.cleaned_data.get("activity_type") try: num = int(activity_type) if num > ActivityType.objects.all().count(): raise forms.ValidationError(self.error_messages["invalid_activity_type"], code="invalid_activity_type") except ValueError: raise forms.ValidationError(self.error_messages["invalid_activity_type"], code="invalid_activity_type") return activity_type def clean(self): start_time = self.cleaned_data['start_time'] now = timezone.now() if start_time < now: self.add_error('start_time', self.error_messages['start_time_error']) end_time = self.cleaned_data['end_time'] if end_time < start_time: self.add_error('end_time', self.error_messages['end_time_error']) def save(self, commit=True): obj = super(ActivityCreationForm, self).save(commit=False) # add the additional data to the act obj obj.last_length = int(self.cleaned_data["day"])*24*60 + int(self.cleaned_data["hour"])*60 + int(self.cleaned_data["minute"]) logger.debug(u'上传的持续时间参数为{0}d{1}h{2}m, 计算得到的持续时间为{3}m'.format( self.cleaned_data['day'], self.cleaned_data['hour'], self.cleaned_data['minute'], obj.last_length )) type_no = int(self.cleaned_data.get("activity_type")) print self.cleaned_data obj.activity_type = list(ActivityType.objects.all())[type_no] if self.cleaned_data['poster'] is not None or not self.is_bound: obj.poster = self.cleaned_data['poster'] # reward system if self.cleaned_data['present']: obj.reward_gift = True obj.reward_gift_detail = self.cleaned_data['present'] else: obj.reward_gift = False if self.cleaned_data['reward']: obj.reward = self.cleaned_data['reward'] else: obj.reward = 0 obj.is_active = False # 创建的表格在问卷生成以后才会有效 obj.host = self.user if not obj.host.profile.identified and self.instance.pk is None: obj.identified = False obj.reward_for_share = 0 obj.reward_for_share_and_finished_percentage = 0 obj.reward_share_limit = 0 elif obj.host.profile.identified: obj.identified = True if commit: obj.save() # copy a new instance of the act object if obj.poster: new_obj = copy.deepcopy(obj) create_zipped_poster.delay(new_obj, force=True) # create_share_thumbnail(new_obj, force=True) return obj class Meta: model = Activity fields = ("name", "host_name", "location", "description", "start_time", "end_time", "max_attend", "city", "province") widgets = { "name": forms.TextInput(attrs={ "id": "name", "class": "content", "placeholder": u"请输入活动名称" }), "host_name": forms.TextInput(attrs={ "id": "host", "name": "host", "class": "content host", "readonly": "readonly" }) , "location": forms.TextInput(attrs={ "id": "detail-addr", "class": "content", "placeholder": u"请输入活动地点" }), "start_time": forms.TextInput(attrs={ "id": "startdate", "name": "startdate", "class": "form-control bday-i", "size": "16", "value": "", "readonly placeholder": u"请选择活动开始时间" }), "end_time": forms.TextInput(attrs={ "id": "enddate", "name": "enddate", "class": "form-control bday-i", "size": "16", "value": "", "readonly placeholder": u"请选择活动结束时间" }), "max_attend": forms.NumberInput(attrs={ "class": "content", }), "description": forms.Textarea(attrs={ "id": "desc", "class": "", "placeholder": u"请输入活动简介" }), }
def __init__(self, *args, **kwargs): super(ShippingRuleForm, self).__init__(*args, **kwargs) if 'partner' in kwargs['initial']: self.fields['partner'].widget = forms.HiddenInput() else: pass
forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter question here" }), "correct_answer": forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter answer here" }), }) PlayerAnswerModelFormSet = modelformset_factory( PlayerAnswer, fields=( "question", "player_answer", ), extra=0, widgets={ "question": forms.HiddenInput(attrs={ "class": "form-control", "readonly": True }), "player_answer": forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter answer here" }) })
def __init__(self, *args, **kwargs): super(EditorsPickForm, self).__init__(*args, **kwargs) self.fields['page'].widget = forms.HiddenInput()
class AdvancedFilterQueryForm(CleanWhiteSpacesMixin, forms.Form): """ Build the query from field, operator and value """ OPERATORS = ( ("iexact", _("Equals")), ("icontains", _("Contains")), ("iregex", _("One of")), ("range", _("DateTime Range")), ("isnull", _("Is NULL")), ("istrue", _("Is TRUE")), ("isfalse", _("Is FALSE")), ("lt", _("Less Than")), ("gt", _("Greater Than")), ("lte", _("Less Than or Equal To")), ("gte", _("Greater Than or Equal To")), ) FIELD_CHOICES = ( ("_OR", _("Or (mark an or between blocks)")), ) field = forms.ChoiceField(required=True, widget=forms.Select( attrs={'class': 'query-field'}), label=_('Field')) operator = forms.ChoiceField( label=_('Operator'), required=True, choices=OPERATORS, initial="iexact", widget=forms.Select(attrs={'class': 'query-operator'})) value = VaryingTypeCharField(required=True, widget=forms.TextInput( attrs={'class': 'query-value'}), label=_('Value')) value_from = forms.DateTimeField(widget=forms.HiddenInput( attrs={'class': 'query-dt-from'}), required=False) value_to = forms.DateTimeField(widget=forms.HiddenInput( attrs={'class': 'query-dt-to'}), required=False) negate = forms.BooleanField(initial=False, required=False, label=_('Negate')) def _build_field_choices(self, fields): """ Iterate over passed model fields tuple and update initial choices. """ return tuple(sorted( ((fquery, capfirst(fname)) for fquery, fname in fields.items()), key=lambda f: f[1].lower()) ) + self.FIELD_CHOICES def _build_query_dict(self, formdata=None): """ Take submitted data from form and create a query dict to be used in a Q object (or filter) """ if self.is_valid() and formdata is None: formdata = self.cleaned_data key = "{field}__{operator}".format(**formdata) if formdata['operator'] == "isnull": return {key: None} elif formdata['operator'] == "istrue": return {formdata['field']: True} elif formdata['operator'] == "isfalse": return {formdata['field']: False} return {key: formdata['value']} @staticmethod def _parse_query_dict(query_data, model): """ Take a list of query field dict and return data for form initialization """ operator = 'iexact' if query_data['field'] == '_OR': query_data['operator'] = operator return query_data parts = query_data['field'].split('__') if len(parts) < 2: field = parts[0] else: if parts[-1] in dict(AdvancedFilterQueryForm.OPERATORS).keys(): field = '__'.join(parts[:-1]) operator = parts[-1] else: field = query_data['field'] query_data['field'] = field mfield = get_fields_from_path(model, query_data['field']) if not mfield: raise Exception('Field path "%s" could not be followed to a field' ' in model %s', query_data['field'], model) else: mfield = mfield[-1] # get the field object if query_data['value'] is None: query_data['operator'] = "isnull" elif query_data['value'] is True: query_data['operator'] = "istrue" elif query_data['value'] is False: query_data['operator'] = "isfalse" else: if isinstance(mfield, DateField): # this is a date/datetime field query_data['operator'] = "range" # default else: query_data['operator'] = operator # default if isinstance(query_data.get('value'), list) and query_data['operator'] == 'range': date_from = date_to_string(query_data.get('value_from')) date_to = date_to_string(query_data.get('value_to')) query_data['value'] = ','.join([date_from, date_to]) return query_data def set_range_value(self, data): """ Validates date range by parsing into 2 datetime objects and validating them both. """ dtfrom = data.pop('value_from') dtto = data.pop('value_to') if dtfrom is dtto is None: self.errors['value'] = ['Date range requires values'] raise forms.ValidationError([]) data['value'] = (dtfrom, dtto) def clean(self): cleaned_data = super().clean() if cleaned_data.get('operator') == "range": if ('value_from' in cleaned_data and 'value_to' in cleaned_data): self.set_range_value(cleaned_data) return cleaned_data def make_query(self, *args, **kwargs): """ Returns a Q object from the submitted form """ query = Q() # initial is an empty query query_dict = self._build_query_dict(self.cleaned_data) if 'negate' in self.cleaned_data and self.cleaned_data['negate']: query = query & ~Q(**query_dict) else: query = query & Q(**query_dict) return query def __init__(self, model_fields={}, *args, **kwargs): super().__init__(*args, **kwargs) self.FIELD_CHOICES = self._build_field_choices(model_fields) self.fields['field'].choices = self.FIELD_CHOICES if not self.fields['field'].initial: self.fields['field'].initial = self.FIELD_CHOICES[0]
class Meta: fields = "__all__" model = models.Observation widgets = {"sample": forms.HiddenInput()}
def editingSetup(self, dataProduct): self.fields['portableDataFile'].widget = forms.HiddenInput() self.fields['manufacturerDataFile'].widget = forms.HiddenInput() self.fields['portableDataFile'].initial = dataProduct.portable_data_file self.fields['manufacturerDataFile'].initial = dataProduct.manufacturer_data_file
from django import forms # global fields hidden_filename_field = forms.CharField(widget=forms.HiddenInput(), required=False) hidden_model = forms.CharField(widget=forms.HiddenInput(), required=False) #hidden_csv_content_field = forms.CharField(widget=forms.HiddenInput(),required = False) hidden_csv_raw_field = forms.CharField(widget=forms.HiddenInput(), required=False) hidden_rdf_array_field = forms.CharField(widget=forms.HiddenInput(), required=False) hidden_rdf_prefix_field = forms.CharField(widget=forms.HiddenInput(), required=False) #hidden_csv_dialect_field = forms.CharField(widget=forms.HiddenInput(),required = False) class DataChoiceForm(forms.Form): list = [ ('1', 'choose'), ('2', 'your'), ('3', 'file'), ('4', 'here'), ] fileList = forms.ChoiceField( choices=list, required=False, ) fileList.widget.attrs['class'] = 'data_source_select' fileList.widget.attrs['size'] = '5' initial = {'max_number': '3'}
class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): logger = logging.getLogger(__name__) data_atual = timezone.now() tipo = forms.ModelChoiceField( required=True, label=_('Tipo de Audiência Pública'), queryset=TipoAudienciaPublica.objects.all().order_by('nome')) tipo_materia = forms.ModelChoiceField( label=_('Tipo Matéria'), required=False, queryset=TipoMateriaLegislativa.objects.all(), empty_label=_('Selecione')) numero_materia = forms.CharField(label=_('Número Matéria'), required=False) ano_materia = forms.CharField(label=_('Ano Matéria'), required=False) materia = forms.ModelChoiceField(required=False, widget=forms.HiddenInput(), queryset=MateriaLegislativa.objects.all()) parlamentar_autor = forms.ModelChoiceField( label=_("Parlamentar Autor"), required=False, queryset=Parlamentar.objects.all()) requerimento = forms.ModelChoiceField( label=_("Requerimento"), required=False, queryset=MateriaLegislativa.objects.select_related("tipo").filter( tipo__descricao="Requerimento")) class Meta: model = AudienciaPublica fields = [ 'tipo', 'numero', 'nome', 'tema', 'data', 'hora_inicio', 'hora_fim', 'observacao', 'audiencia_cancelada', 'parlamentar_autor', 'requerimento', 'url_audio', 'url_video', 'upload_pauta', 'upload_ata', 'upload_anexo', 'tipo_materia', 'numero_materia', 'ano_materia', 'materia' ] def __init__(self, **kwargs): super(AudienciaForm, self).__init__(**kwargs) tipos = [] if not self.fields['tipo'].queryset: tipos.append( TipoAudienciaPublica.objects.create(nome='Audiência Pública', tipo='A')) tipos.append( TipoAudienciaPublica.objects.create(nome='Plebiscito', tipo='P')) tipos.append( TipoAudienciaPublica.objects.create(nome='Referendo', tipo='R')) tipos.append( TipoAudienciaPublica.objects.create(nome='Iniciativa Popular', tipo='I')) for t in tipos: t.save() def clean(self): cleaned_data = super(AudienciaForm, self).clean() if not self.is_valid(): return cleaned_data materia = cleaned_data['numero_materia'] ano_materia = cleaned_data['ano_materia'] tipo_materia = cleaned_data['tipo_materia'] parlamentar_autor = cleaned_data["parlamentar_autor"] requerimento = cleaned_data["requerimento"] if materia and ano_materia and tipo_materia: try: self.logger.debug( "Tentando obter MateriaLegislativa %s nº %s/%s." % (tipo_materia, materia, ano_materia)) materia = MateriaLegislativa.objects.get(numero=materia, ano=ano_materia, tipo=tipo_materia) except ObjectDoesNotExist: msg = _('A matéria %s nº %s/%s não existe no cadastro' ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) self.logger.warn( 'A MateriaLegislativa %s nº %s/%s não existe no cadastro' ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) raise ValidationError(msg) else: self.logger.info( "MateriaLegislativa %s nº %s/%s obtida com sucesso." % (tipo_materia, materia, ano_materia)) cleaned_data['materia'] = materia else: campos = [materia, tipo_materia, ano_materia] if campos.count(None) + campos.count('') < len(campos): msg = _( 'Preencha todos os campos relacionados à Matéria Legislativa' ) self.logger.warn( 'Algum campo relacionado à MatériaLegislativa %s nº %s/%s \ não foi preenchido.' % (tipo_materia, materia, ano_materia)) raise ValidationError(msg) if not cleaned_data['numero']: ultima_audiencia = AudienciaPublica.objects.all().order_by( 'numero').last() if ultima_audiencia: cleaned_data['numero'] = ultima_audiencia.numero + 1 else: cleaned_data['numero'] = 1 if self.cleaned_data['hora_inicio'] and self.cleaned_data['hora_fim']: if self.cleaned_data['hora_fim'] < self.cleaned_data['hora_inicio']: msg = _( 'A hora de fim ({}) não pode ser anterior a hora de início({})' .format(self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'])) self.logger.warn('Hora de fim anterior à hora de início.') raise ValidationError(msg) if parlamentar_autor.autor.first() not in requerimento.autores.all(): raise ValidationError( "Parlamentar Autor selecionado não faz parte da autoria do Requerimento selecionado." ) upload_pauta = self.cleaned_data.get('upload_pauta', False) upload_ata = self.cleaned_data.get('upload_ata', False) upload_anexo = self.cleaned_data.get('upload_anexo', False) if upload_pauta: validar_arquivo(upload_pauta, "Pauta da Audiência Pública") if upload_ata: validar_arquivo(upload_ata, "Ata da Audiência Pública") if upload_anexo: validar_arquivo(upload_anexo, "Anexo da Audiência Pública") return cleaned_data
class DisableEntityForm(forms.Form): disable_reason = forms.TypedChoiceField( choices=DisableReason.choices(), error_messages={'invalid': _(u"Expecting one option selected")}, widget=forms.RadioSelect(attrs={ 'class': '', 'autofocus': 'on' }), label=_(u"Select a reason"), coerce=int, empty_value=None, ) comment_input = forms.CharField( required=False, label=_("Comments"), widget=forms.Textarea(attrs={ 'cols': 80, 'rows': 5 }), ) tally_id = forms.CharField( required=False, widget=forms.HiddenInput(), ) center_code_input = forms.CharField( required=False, widget=forms.HiddenInput(), ) station_number_input = forms.CharField( required=False, widget=forms.HiddenInput(), ) race_id_input = forms.CharField( required=False, widget=forms.HiddenInput(), ) def clean(self): if self.is_valid(): cleaned_data = super(DisableEntityForm, self).clean() tally_id = cleaned_data.get('tally_id') center_code = cleaned_data.get('center_code_input') station_number = cleaned_data.get('station_number_input') race_id = cleaned_data.get('race_id_input') if center_code: try: if station_number: Station.objects.get(station_number=station_number, center__code=center_code, center__tally__id=tally_id) else: Center.objects.get(tally__id=tally_id, code=center_code) except Center.DoesNotExist: raise forms.ValidationError( _('Center Number does not exist')) except Station.DoesNotExist: raise forms.ValidationError( _('Station Number does not exist')) elif race_id: try: Ballot.objects.get(id=race_id) except Ballot.DoesNotExist: raise forms.ValidationError(_('Race does not exist')) else: raise forms.ValidationError(_('Error')) return cleaned_data def save(self): if self.is_valid(): tally_id = self.cleaned_data.get('tally_id') center_code = self.cleaned_data.get('center_code_input') station_number = self.cleaned_data.get('station_number_input') race_id = self.cleaned_data.get('race_id_input') disable_reason = self.cleaned_data.get('disable_reason') comment = self.cleaned_data.get('comment_input') result = None if not race_id: result = disable_enable_entity(center_code, station_number, disable_reason, comment, tally_id) else: result = disable_enable_race(race_id, disable_reason, comment, tally_id) return result
class Meta: model = Questionnaire exclude = () widgets = {'order': forms.HiddenInput()}
class LocationId(forms.Form): stop_location_id = forms.CharField(label='Location ID', max_length=4, required=True) lat = forms.HiddenInput() lon = forms.HiddenInput()
class GoldSubscriptionForm(StripeResourceMixin, StripeModelForm): """Gold subscription payment form This extends the common base form for handling Stripe subscriptions. Credit card fields for card number, expiry, and CVV are extended from :py:class:`StripeModelForm`, with additional methods from :py:class:`StripeResourceMixin` for common operations against the Stripe API. """ class Meta(object): model = GoldUser fields = ['last_4_digits', 'level'] last_4_digits = forms.CharField( required=True, min_length=4, max_length=4, widget=forms.HiddenInput( attrs={'data-bind': 'valueInit: card_digits, value: card_digits'})) level = forms.ChoiceField( required=True, choices=LEVEL_CHOICES, ) def clean(self): self.instance.user = self.customer return super(GoldSubscriptionForm, self).clean() def validate_stripe(self): subscription = self.get_subscription() self.instance.stripe_id = subscription.customer self.instance.subscribed = True def get_customer_kwargs(self): return { 'description': self.customer.get_full_name() or self.customer.username, 'email': self.customer.email, 'id': self.instance.stripe_id or None } def get_subscription(self): customer = self.get_customer() try: # TODO get the first sub more intelligently subscriptions = customer.subscriptions.all(limit=5) subscription = subscriptions.data[0] subscription.plan = self.cleaned_data['level'] if 'stripe_token' in self.cleaned_data: subscription.source = self.cleaned_data['stripe_token'] subscription.save() return subscription except (InvalidRequestError, AttributeError, IndexError): subscription = customer.subscriptions.create( plan=self.cleaned_data['level'], source=self.cleaned_data['stripe_token']) return subscription def clear_card_data(self): super(GoldSubscriptionForm, self).clear_card_data() self.data['last_4_digits'] = None
class ConfirmForm(forms.Form): """Hidden form used by ExpressPay flow to keep track of payer information.""" token = forms.CharField(max_length=255, widget=forms.HiddenInput()) PayerID = forms.CharField(max_length=255, widget=forms.HiddenInput())
class RegisterPaymentForm(forms.Form): paid = forms.BooleanField(initial=True, widget=forms.HiddenInput()) payment_registered_on = forms.DateField(initial=date.today(), widget=forms.HiddenInput())
class PayPalPaymentsForm(forms.Form): """ Creates a PayPal Payments Standard "Buy It Now" button, configured for a selling a single item with no shipping. For a full overview of all the fields you can set (there is a lot!) see: http://tinyurl.com/pps-integration Usage: >>> f = PayPalPaymentsForm(initial={'item_name':'Widget 001', ...}) >>> f.render() u'<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> ...' """ CMD_CHOICES = (("_xclick", "Buy now or Donations"), ("_donations", "Donations"), ("_cart", "Shopping cart"), ("_xclick-subscriptions", "Subscribe")) SHIPPING_CHOICES = ((1, "No shipping"), (0, "Shipping")) NO_NOTE_CHOICES = ((1, "No Note"), (0, "Include Note")) RECURRING_PAYMENT_CHOICES = ((1, "Subscription Payments Recur"), (0, "Subscription payments do not recur")) REATTEMPT_ON_FAIL_CHOICES = ((1, "reattempt billing on Failure"), (0, "Do Not reattempt on failure")) BUY = 'buy' SUBSCRIBE = 'subscribe' DONATE = 'donate' # Where the money goes. business = forms.CharField(widget=ValueHiddenInput()) # Item information. amount = forms.IntegerField(widget=ValueHiddenInput()) item_name = forms.CharField(widget=ValueHiddenInput()) item_number = forms.CharField(widget=ValueHiddenInput()) quantity = forms.CharField(widget=ValueHiddenInput()) # Subscription Related. a1 = forms.CharField(widget=ValueHiddenInput()) # Trial 1 Price p1 = forms.CharField(widget=ValueHiddenInput()) # Trial 1 Duration t1 = forms.CharField(widget=ValueHiddenInput() ) # Trial 1 unit of Duration, default to Month a2 = forms.CharField(widget=ValueHiddenInput()) # Trial 2 Price p2 = forms.CharField(widget=ValueHiddenInput()) # Trial 2 Duration t2 = forms.CharField(widget=ValueHiddenInput() ) # Trial 2 unit of Duration, default to Month a3 = forms.CharField(widget=ValueHiddenInput()) # Subscription Price p3 = forms.CharField(widget=ValueHiddenInput()) # Subscription Duration t3 = forms.CharField(widget=ValueHiddenInput() ) # Subscription unit of Duration, default to Month src = forms.CharField( widget=ValueHiddenInput()) # Is billing recurring? default to yes sra = forms.CharField(widget=ValueHiddenInput() ) # Reattempt billing on failed cc transaction no_note = forms.CharField(widget=ValueHiddenInput()) # Can be either 1 or 2. 1 = modify or allow new subscription creation, 2 = modify only modify = forms.IntegerField(widget=ValueHiddenInput() ) # Are we modifying an existing subscription? # Localization / PayPal Setup lc = forms.CharField(widget=ValueHiddenInput()) page_style = forms.CharField(widget=ValueHiddenInput()) cbt = forms.CharField(widget=ValueHiddenInput()) # IPN control. notify_url = forms.CharField(widget=ValueHiddenInput()) cancel_return = forms.CharField(widget=ValueHiddenInput()) return_url = forms.CharField(widget=ReservedValueHiddenInput( attrs={"name": "return"})) custom = forms.CharField(widget=ValueHiddenInput()) invoice = forms.CharField(widget=ValueHiddenInput()) # Default fields. cmd = forms.ChoiceField(widget=forms.HiddenInput(), initial=CMD_CHOICES[0][0]) charset = forms.CharField(widget=forms.HiddenInput(), initial="utf-8") currency_code = forms.CharField(widget=forms.HiddenInput(), initial="USD") no_shipping = forms.ChoiceField(widget=forms.HiddenInput(), choices=SHIPPING_CHOICES, initial=SHIPPING_CHOICES[0][0]) def __init__(self, button_type="buy", *args, **kwargs): super(PayPalPaymentsForm, self).__init__(*args, **kwargs) self.button_type = button_type if 'initial' in kwargs: kwargs['initial'] = self._fix_deprecated_paypal_receiver_email( kwargs['initial']) # Dynamically create, so we can support everything PayPal does. for k, v in kwargs['initial'].items(): if k not in self.base_fields: self.fields[k] = forms.CharField(label=k, widget=ValueHiddenInput(), initial=v) def _fix_deprecated_paypal_receiver_email(self, initial_args): if 'business' not in initial_args: if hasattr(settings, 'PAYPAL_RECEIVER_EMAIL'): warn( """The use of the settings.PAYPAL_RECEIVER_EMAIL is Deprecated. The keyword business argument must be given to PayPalPaymentsForm on creation""", DeprecationWarning) initial_args['business'] = settings.PAYPAL_RECEIVER_EMAIL return initial_args def test_mode(self): return getattr(settings, 'PAYPAL_TEST', True) def get_endpoint(self): "Returns the endpoint url for the form." if self.test_mode(): return SANDBOX_POSTBACK_ENDPOINT else: return POSTBACK_ENDPOINT def render(self): return format_html( u"""<form action="{0}" method="post"> {1} <input type="image" src="{2}" border="0" name="submit" alt="Buy it Now" /> </form>""", self.get_endpoint(), self.as_p(), self.get_image()) def sandbox(self): "Deprecated. Use self.render() instead." import warnings warnings.warn( """PaypalPaymentsForm.sandbox() is deprecated. Use the render() method instead.""", DeprecationWarning) return self.render() def get_image(self): return { (True, self.SUBSCRIBE): SUBSCRIPTION_SANDBOX_IMAGE, (True, self.BUY): SANDBOX_IMAGE, (True, self.DONATE): DONATION_SANDBOX_IMAGE, (False, self.SUBSCRIBE): SUBSCRIPTION_IMAGE, (False, self.BUY): IMAGE, (False, self.DONATE): DONATION_IMAGE, }[self.test_mode(), self.button_type] def is_transaction(self): return not self.is_subscription() def is_donation(self): return self.button_type == self.DONATE def is_subscription(self): return self.button_type == self.SUBSCRIBE
class DeleteAccountForm(forms.Form): ''' This form allows the user to deactivate their account. ''' delete_account = forms.CharField(widget=forms.HiddenInput(), initial='delete')
def __init__(self, *args, **kwargs): clinicians = CustomUser.objects.all() instance = None if 'registry_model' in kwargs: self.registry_model = kwargs['registry_model'] del kwargs['registry_model'] else: self.registry_model = None if 'instance' in kwargs and kwargs['instance'] is not None: instance = kwargs['instance'] registry_specific_data = self._get_registry_specific_data(instance) wrapped_data = self._wrap_file_cdes(registry_specific_data) initial_data = kwargs.get('initial', {}) for reg_code in wrapped_data: initial_data.update(wrapped_data[reg_code]) self._update_initial_consent_data(instance, initial_data) kwargs['initial'] = initial_data clinicians = CustomUser.objects.filter( registry__in=kwargs['instance'].rdrf_registry.all()) if "user" in kwargs: self.user = kwargs.pop("user") super(PatientForm, self).__init__(*args, **kwargs) # NB I have moved the constructor clinicians_filtered = [c.id for c in clinicians if c.is_clinician] self.fields["clinician"].queryset = CustomUser.objects.filter( id__in=clinicians_filtered) # clinicians field should only be visible for registries which # support linking of patient to an "owning" clinician if self.registry_model: if not self.registry_model.has_feature("clinicians_have_patients"): self.fields["clinician"].widget = forms.HiddenInput() registries = Registry.objects.all() if self.registry_model: registries = registries.filter(id=self.registry_model.id) self.fields["rdrf_registry"].queryset = registries if hasattr(self, 'user'): user = self.user # working groups shown should be only related to the groups avail to the # user in the registry being edited if not user.is_superuser: if self._is_parent_editing_child(instance): # see FKRP #472 self.fields[ "working_groups"].widget = forms.SelectMultiple( attrs={'readonly': 'readonly'}) self.fields[ "working_groups"].queryset = instance.working_groups.all( ) else: self.fields[ "working_groups"].queryset = WorkingGroup.objects.filter( registry=self.registry_model, id__in=[ wg.pk for wg in self.user.working_groups.all() ]) else: self.fields[ "working_groups"].queryset = WorkingGroup.objects.filter( registry=self.registry_model) # field visibility restricted no non admins if not user.is_superuser: if not self.registry_model: registry = user.registry.all()[0] else: registry = self.registry_model working_groups = user.groups.all() for field in self.fields: hidden = False readonly = False for wg in working_groups: try: field_config = DemographicFields.objects.get( registry=registry, group=wg, field=field) hidden = hidden or field_config.hidden readonly = readonly or field_config.readonly except DemographicFields.DoesNotExist: pass if hidden: self.fields[field].widget = forms.HiddenInput() self.fields[field].label = "" if readonly and not hidden: self.fields[field].widget = forms.TextInput( attrs={'readonly': 'readonly'}) if self._is_adding_patient(kwargs): self._setup_add_form()
def __init__(self, *args, **kwargs): super(DatabaseForm, self).__init__(*args, **kwargs) self.fields['is_in_quarantine'].widget = forms.HiddenInput()
class ProductForm(CoreProductForm): too_rigid = forms.CharField(required=False, widget=forms.HiddenInput()) not_rectangular = forms.CharField(required=False, widget=forms.HiddenInput()) thickness_variations = forms.CharField(required=False, widget=forms.HiddenInput()) YES, NO = True, False YES_NO = ((YES, _('Yes')), (NO, _('No'))) is_name_matched = forms.NullBooleanField( label=_("Shipping address name matches account holder name?"), #initial=True, widget=forms.RadioSelect(choices=YES_NO)) prohibited_items_msg = forms.CharField(label=_( "Prohibited items description - this will be sent to the customer"), max_length=128, required=False) PENDING, PREDEFINED_WAITING_FOR_CONSOLIDATION,\ WAITING_FOR_CONSOLIDATION, PAID, CONSOLIDATION_TAKING_PLACE,\ CONSOLIDATION_DONE, HANDLING_SPECIAL_REQUESTS,\ HANDLING_SPECIAL_REQUESTS_DONE, SHIPPED, SETTLED,\ PREDEFINED_PACKED, PACKED,\ POSTAGE_PURCHASED, POSTAGE_MISMATCH, \ RETURNED_TO_SENDER, DISCARDED,\ CONTAINS_PROHIBITED_ITEMS, PENDING_RETURNED_PACKAGE,\ PRE_PENDING, LOST_IN_WAREHOUSE, PENDING_CLEARANCE = ( 'pending', 'predefined_waiting_for_consolidation', 'waiting_for_consolidation', 'paid', 'consolidation_taking_place', 'consolidation_done', 'handling_special_requests', 'handling_special_requests_done', 'shipped', 'settled', 'predefined_packed', 'packed', 'postage_purchased', 'postage_mismatch', 'returned_to_sender', 'discarded', 'contains_prohibited_items', 'pending_returned_package', 'pre_pending', 'lost_in_warehouse', 'pending_clearance' ) STATUS_CHOICES = ( ('', '-------------'), (PENDING, _('Pending')), (PRE_PENDING, _('Pre pending')), (PREDEFINED_WAITING_FOR_CONSOLIDATION, _('Predefined waiting for consolidation')), (WAITING_FOR_CONSOLIDATION, _('Waiting for consolidation')), (PAID, _('Paid')), (CONSOLIDATION_TAKING_PLACE, _('Consolidation taking place')), (CONSOLIDATION_DONE, _('Consolidation done')), (HANDLING_SPECIAL_REQUESTS, _('Handling extra services')), (HANDLING_SPECIAL_REQUESTS_DONE, _('Handling extra services done')), (SHIPPED, _('Shipped')), (SETTLED, _('Settled')), (PREDEFINED_PACKED, _('Predefined packed')), (PACKED, _('Packed')), (POSTAGE_PURCHASED, _('Postage purchased')), (POSTAGE_MISMATCH, _('Postage mismatch')), (RETURNED_TO_SENDER, _('Returned to sender')), (DISCARDED, _('Discarded')), (CONTAINS_PROHIBITED_ITEMS, _('Contains prohibited items')), (PENDING_RETURNED_PACKAGE, _('Returned package')), (LOST_IN_WAREHOUSE, _('Lost in warehouse')), (PENDING_CLEARANCE, _('Pending payment clearance')), ) NEEDED_FIELDS = [ 'upc', 'owner', 'title', 'condition', 'status', 'is_client_id_missing', 'combined_products', 'is_name_matched', 'too_rigid', 'not_rectangular', 'thickness_variations', 'is_contain_prohibited_items', 'prohibited_items_msg', 'is_sent_outside_usa', 'battery_status', 'merchant_zipcode' ] STAFF_FIELDS = ['status'] def __init__(self, product_class, *args, **kwargs): is_staff = kwargs.pop('is_staff', False) #generate upc only for new products instance = kwargs.get('instance') if not instance: self.set_initial_upc_value(kwargs) super(ProductForm, self).__init__(product_class, *args, **kwargs) self.fields['owner'] = UserModelChoiceField( label='Customer ID (suite number) or name', required=True, queryset=User.objects.filter(profile__isnull=False, is_staff=False), widget=UserSelect( attrs={'data-action': 'predefined_special_requests'})) self.fields['upc'].widget.attrs['readonly'] = 'readonly' self.fields['upc'].label = 'Package ID' self.fields['upc'].help_text = '' self.fields['condition'].required = True self.fields['title'].required = True self.fields['title'].label = 'Merchant name' self.fields['merchant_zipcode'].required = True self.fields['is_client_id_missing'].required = True self.fields['is_sent_outside_usa'].required = True self.fields['battery_status'].required = True self.fields['is_contain_prohibited_items'].required = True #show only relevant fields + all product attributes for key in self.fields.keys(): if key not in self.NEEDED_FIELDS and not key.startswith('attr_'): self.fields.pop(key) #show only combined_products for consolidated packages if not instance or not instance.is_consolidated: self.fields.pop('combined_products') else: #show only packages self.fields[ 'combined_products'].queryset = instance.combined_products.all( ) #additional receiver is only applicable for new package intake #show status only when edit a product if instance: self.fields.pop('is_name_matched') self.fields['status'] = forms.ChoiceField( choices=self.STATUS_CHOICES, initial=instance.status if instance else None, required=False) else: self.fields.pop('status') #if user isn't staff remove staff only fields #if not is_staff: # for field in self.STAFF_FIELDS: # self.fields.pop(field) #staff only fields, currently we only have 1 such field #else: try: #enforce this order LxWxH Weight length = self.fields.pop('attr_length') width = self.fields.pop('attr_width') height = self.fields.pop('attr_height') weight = self.fields.pop('attr_weight') prohibited_items_msg = self.fields.pop('prohibited_items_msg') self.fields.insert(6, 'prohibited_items_msg', prohibited_items_msg) self.fields.insert(-1, 'attr_length', length) self.fields.insert(-1, 'attr_width', width) self.fields.insert(-1, 'attr_height', height) self.fields.insert(-1, 'attr_weight', weight) #wrap is_envelope field to enforce the user to make a selection and make it show first self.fields.pop('attr_is_envelope') self.fields.insert( 0, 'attr_is_envelope', forms.NullBooleanField( label=_("envelope?"), widget=forms.RadioSelect(choices=self.YES_NO))) #only packages have the above attributes except KeyError: pass @staticmethod def make_bool(str): if str and str.lower() == 'true': return True return False def set_initial_upc_value(self, kwargs): kwargs['initial']['upc'] = generate_upc() #def clean_attr_weight(self): # #validate that the weight of consolidated package is not exceeding the max weight per destination # #since we don't want to split the consolidated package into smaller # #packages we need to make sure it can be shipped via USPS to any country # #We got some max weights for selected countries, if we can't find the country we use # #default max_weight of 44 which should be fine with all countries # #we take the owner country to determine the shipping destination - this should answer 99.99% # #of the cases # weight = self.cleaned_data.get('attr_weight') # if self.instance.id and\ # self.instance.is_consolidated: # owner_profile = self.instance.owner.get_profile() # owner_country = owner_profile.country # owner_proxy_score = owner_profile.proxy_score # max_weight = settings.CONSOLIDATED_PACKAGE_MAX_WEIGHT['DEFAULT'] # if owner_proxy_score is not None and owner_proxy_score == 0: #user is not behind a proxy, we can take his country into account # max_weight = settings.CONSOLIDATED_PACKAGE_MAX_WEIGHT.get(owner_country, max_weight) # if weight > max_weight: # raise forms.ValidationError(_("Max weight of consolidated package must not exceed %d lbs, please contact" # " manager before continuing.") % max_weight) # return weight def clean_attr_is_envelope(self): is_envelope = self.cleaned_data.get('attr_is_envelope') if is_envelope is None: raise forms.ValidationError(_("This field is required")) return is_envelope def clean_is_client_id_missing(self): is_client_id_missing = self.cleaned_data.get('is_client_id_missing') if is_client_id_missing is None: raise forms.ValidationError(_("This field is required")) return is_client_id_missing def clean_is_sent_outside_usa(self): is_sent_outside_usa = self.cleaned_data.get('is_sent_outside_usa') if is_sent_outside_usa is None: raise forms.ValidationError(_("This field is required")) return is_sent_outside_usa def clean_is_contain_prohibited_items(self): is_contain_prohibited_items = self.cleaned_data.get( 'is_contain_prohibited_items') if is_contain_prohibited_items is None: raise forms.ValidationError(_("This field is required")) return is_contain_prohibited_items def clean_is_name_matched(self): is_name_matched = self.cleaned_data.get('is_name_matched') if is_name_matched is None: raise forms.ValidationError(_("This field is required")) return is_name_matched def check_envelope_limitations(self): envelope_limitations = [ self.make_bool(self.cleaned_data.get('too_rigid')), self.make_bool(self.cleaned_data.get('not_rectangular')), self.make_bool(self.cleaned_data.get('thickness_variations')) ] #check if envelope passed USPS limitations if any(envelope_limitations) or \ self.cleaned_data.get('attr_weight', 0.0) > settings.USPS_MAX_ENVELOPE_WEIGHT: self.cleaned_data['attr_is_envelope'] = False def clean(self): """ Fixed oscar's bug where submitting the product form with no title """ data = self.cleaned_data if 'parent' not in data and not data.get('title'): raise forms.ValidationError(_("This field is required")) elif 'parent' in data and data['parent'] is None and not data['title']: raise forms.ValidationError(_("Parent products must have a title")) #change is_envelope value to False if envelope failed any limitation self.check_envelope_limitations() return super(ProductForm, self).clean() def save(self): """ We modified the package creating view to show only relevant attributes therefore not all attributes exist on form so we need to wrap it up with KeyError exception handling to bypass the missing attributes """ object = super(CoreProductForm, self).save(commit=False) object.product_class = self.product_class #make sure merchant name is capitalized object.title = string.capwords(object.title) is_populated = False for attribute in self.product_class.attributes.all(): try: value = self.cleaned_data['attr_%s' % attribute.code] except KeyError: continue else: if not is_populated: #FIX oscar bug: populate product attributes before changing their values try: getattr(object.attr, attribute.code) except AttributeError: pass is_populated = True setattr(object.attr, attribute.code, value) if not object.upc: object.upc = None object.save() self.save_m2m() return object class Meta: YES, NO = True, False YES_NO = ((YES, _('Yes')), (NO, _('No'))) model = Product fields = [ 'upc', 'title', 'merchant_zipcode', 'parent', 'owner', 'status', 'condition', 'is_client_id_missing', 'combined_products', 'is_contain_prohibited_items', 'is_sent_outside_usa', 'battery_status' ] widgets = { 'is_client_id_missing': forms.RadioSelect(choices=YES_NO), 'is_sent_outside_usa': forms.RadioSelect(choices=YES_NO), 'is_contain_prohibited_items': forms.RadioSelect(choices=YES_NO), }