Задать вопрос
Ответы пользователя по тегу Django
  • Как конвертировать модель Django в Json Schema?

    Khikmat
    @Khikmat Автор вопроса
    sim3x вот велосипед-та здесь нужен :) Так как DRF и его TemplateHTMLRenderer рендерить уже готовую форму которую я не смогу использовать с AngularJS Material. На данный момент я сделал миксин для формы в Django:
    class MDSwitchRenderer(RadioFieldRenderer): 
    	def render(self):
    		return render_to_string('switch_widget.html', {'field': self})
    
    
    class MDSwitch(RadioSelect): 
    	renderer = MDSwitchRenderer
    
    
    class MDSelect(Widget):
    	allow_multiple_selected = False
    
    	def __init__(self, attrs=None, choices=()):
    		super(MDSelect, self).__init__(attrs)
    		self.choices = list(choices)
    
    	def render(self, name, value, attrs=None, choices=()):
    		if value is None:
    			value = ''
    		final_attrs = self.build_attrs(attrs, name=name)
    		output = [format_html('<md-select{}>', flatatt(final_attrs))]
    		options = self.render_options(choices, [value])
    		if options:
    			output.append(options)
    		output.append('</md-select>')
    		return mark_safe('\n'.join(output))
    
    	def render_option(self, selected_choices, option_value, option_label):
    		if option_value is None:
    			option_value = ''
    		option_value = force_text(option_value)
    		if option_value in selected_choices:
    			selected_html = mark_safe(' selected')
    			if not self.allow_multiple_selected:
    				selected_choices.remove(option_value)
    		else:
    			selected_html = ''
    		return format_html('<md-option data-ng-value="{}"{}>{}</md-option>', option_value, selected_html, force_text(option_label))
    
    	def render_options(self, choices, selected_choices):
    		selected_choices = set(force_text(v) for v in selected_choices)
    		output = []
    		for option_value, option_label in chain(self.choices, choices):
    			if isinstance(option_label, (list, tuple)):
    				output.append(format_html('<md-optgroup label="{}">', force_text(option_value)))
    				for option in option_label:
    					output.append(self.render_option(selected_choices, *option))
    				output.append('</md-optgroup>')
    			else:
    				output.append(self.render_option(selected_choices, option_value, option_label))
    		return '\n'.join(output)
    
    
    class MDSelectMultiple(MDSelect):
    	allow_multiple_selected = True
    
    	def render(self, name, value, attrs=None, choices=()):
    		if value is None:
    			value = []
    		final_attrs = self.build_attrs(attrs, name=name)
    		output = [format_html('<md-select multiple="multiple"{}>', flatatt(final_attrs))]
    		options = self.render_options(choices, value)
    		if options:
    			output.append(options)
    		output.append('</md-select>')
    		return mark_safe('\n'.join(output))
    
    	def value_from_datadict(self, data, files, name):
    		if isinstance(data, MultiValueDict):
    			return data.getlist(name)
    		return data.get(name)
    
    
    class MDFormMixin(object):
    	"""
    	Angular Material Design form mixin
    	"""
    
    	def __init__(self, *args, **kwargs):
    		super(MDFormMixin, self).__init__(args, kwargs)
    		for field_name in self.fields:
    			field = self.fields.get(field_name)
    			if field:
    				if type(field) in (ModelChoiceField, ):
    					field.empty_label = None
    					field.widget = MDSelect(choices=field.choices)
    				elif type(field) in (ModelMultipleChoiceField, ):
    					field.empty_label = None
    					field.widget = MDSelectMultiple(choices=field.choices)
    
    				if type(field.widget) in (TextInput, Textarea):
    					field.widget.attrs.update({'md-maxlength': field.max_length, })
    				#elif type(field.widget) in (TimeInput, ): # FIXME: Remove
    				#	field.widget.input_type = 'time'
    				#	field.widget.attrs.update({'step': 1, })
    				elif type(field.widget) in (Select, ):
    					field.widget = MDSelect(choices=field.choices)
    
    				if field.required:
    					field.widget.attrs.update({'required': 'required'})
    
    				field.widget.attrs.update({'ng-model': 'vm.object.'+field_name})

    template "switch_widget.html":
    <md-radio-group ng-model="vm.object.{{ field.name }}">
    {% for choice in field %}
    	<md-radio-button ng-value="{{ choice.choice_value|lower }}">
    		{{ choice.choice_label }}
    	</md-radio-button>
    {% endfor %}
    </md-radio-group>

    и template самой формы "django_form.html":
    {% if form.fieldsets %}
    <md-content>
    {% for fieldset in form.fieldsets %}
    	<div{% if fieldset.class %} class="{{ fieldset.classes }}"{% endif %}{% if fieldset.description %} layout="{{ fieldset.description }}{% endif %}">
    	{% for field in fieldset %}
    		<md-input-container class="md-block" flex>
    			<label>{{ field.label }}</label>
    			{{ field }}
    			{% if field.help_text %}
    			<div class="hint">{{ field.help_text }}</div>
    			{% endif %}
    			<div ng-messages="vm.objectForm.{{ field.name }}.$error">
    				<div ng-message="required" ng-show="vm.objectForm.{{ field.name }}.$error['required']">Обязательное поле для заполнения!</div>
    				<div ng-message="md-maxlength" ng-show="vm.objectForm.{{ field.name }}.$error['md-maxlength']">Длина строки не должна превышать {{ field.field.max_length }} символов.</div>
    			</div>
    		</md-input-container>
    	{% endfor %}
    	</div>
    {% endfor %}
    </md-content>
    {% endif %}

    Это связка работает. Но у меня возникла проблема когда я начал использовать в Angular ControllerAs :( Когда использовал $scope таких проблем не было :)
    Ответ написан
    Комментировать