Rendering fields manually---Django - python

I am learning to program in django and I have a question, I have been reading the django documentation on how to manually render the form fields, and I have not been able to understand and save the data; when I use form.as_p I can get the data to be saved to my database, but when I try to render it manually or separately I can't. Could someone please explain, then I leave the code I am using
models.py
class CrearUsuario(CreateView):
model = Proveedor
form_class = ProveedorForm
template_name = 'contratacion/formsuser.html'
success_url = reverse_lazy('proveedor')
forms.py
class ProveedorForm(ModelForm):
class Meta:
model = Proveedor
fields = '__all__'
forms.user.html
<form method='POST'>{% csrf_token %}
<div class="row">
<div class="col">
<div class="form-group">
<label class="col-lg-2 control-label">Razon Social</label>
<div class="col-md-3">
{{form.razon_social}}
</div>
</div>
</div>
<div class="col">
<div class="form-group">
<label class="col-lg-2 control-label">Sigla</label>
<div class="col-md-3">
{{form.sigla}}
</div>
</div>
</div>
</div>

Related

Error during template rendering using extra_context django

Hello I'm using extra_context in views and in the HTML I'm passing it, but it seems that I am doing it wrong because I get this error:
ProgrammingError at /informacion-tiendas/add
column InformacionTiendas_informaciontiendas.nombre does not exist
LINE 1: ...ECT "InformacionTiendas_informaciontiendas"."id", "Informaci...
And when commenting the extra_context line in views, the HTML page is already seen without errors, obviously the context does not pass and the inputs do not appear, but at least there are no errors
Does anyone know why?
views.py
class InformacionTiendasAdd(CreateView):
model=InformacionTiendas
form_class=InformacionTiendasForm
template_name='InformacionTiendas/informacion-tiendas-agregar.html'
success_url=reverse_lazy('InformacionTiendas:list_tiendas')
extra_context={'tiendas': InformacionTiendas.objects.all()}
models.py
class InformacionTiendas(models.Model):
nombre=models.CharField(max_length=255)
registro_desde=models.DateTimeField(default=datetime.now )
tax_id=models.IntegerField()
def __str__(self):
return f'{self.nombre} {self.registro_desde} {self.tax_id}'
informacion-agregar-tiendas.html
<form class="needs-validation" novalidate>
{% for tienda in tiendas %}
<div class="row mb-3">
<div class="col-md-12">
<div>
<label class="form-label" for="validationCustom01">Name</label>
{{ tienda.nombre }}
<div class="invalid-feedback">
Please provide the workshop name.
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="validationCustom06">Registration</label>
{{ tienda.registro_desde }}
Please provide workshop`s registration number.
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="validationCustom07">TAX ID</label>
{{ tienda.tax_id }}
<div class="invalid-feedback">
Please provide workshop`s registration number.
</div>
</div>
</div>
</div>
{% endfor %}
</form>
Based on the new information from your edit, it looks like you haven’t migrated the database.
Try running this in your shell:
python manage.py makemigrations
python manage.py migrate

Django ModelForm initial not working for textarea

I have a django ModelForm, I'm trying to populate it with initial values from my views, all fields are populated except for the textarea field. I have no idea why. Any help is appreciated. Thanks!
views.py
name = 'Testing123'
private = True
notes = 'JUST CHECKING'
ctx['header_form'] = NewTemplateForm(initial={'name': name, 'private': private,'notes:': notes})
private is a BooleanField, initial works even for that
name is populated
notes is the only field that isn't being populated.
template.html
I'm rendering the form like this:
{% load widget_tweaks %}
<div class="form-group">
<div class="row" style="margin-bottom: 15px">
<div class="col-lg-6">
<label>{{form.name.label}}</label>
{% render_field form.name class="form-control" required="true" %}
</div>
<div class="col-lg-6" style="margin-top: 23px">
<div class="i-checks"><label> {% render_field form.private type="checkbox" %} <i></i> Make this Template Private </label></div>
</div>
</div>
</div>
<div class="row" style="margin-bottom: 15px">
<div class="col-lg-12">
<label data-error="wrong" data-success="right" for="id_notes">{{form.notes.label}}</label>
{% render_field form.notes class="form-control" %}
</div>
</div>
forms.py
class NewTemplateForm(ModelForm):
class Meta:
model = SalesTemplate
fields = {'name', 'notes', 'private'}
def __init__(self, *args, **kwargs):
super(NewTemplateForm, self).__init__(*args, **kwargs)
self.fields['notes'].widget = forms.Textarea(attrs={'class': 'md-textarea', 'style': 'height: 75px'})
Because there is a typo in your code and you are passing 'notes:' as key instead of 'notes' in this line
ctx['header_form'] = NewTemplateForm(initial={'name': name, 'private': private,
'notes:': notes}) # HERE!

Handle POST/GET forms with Django and Bootstrap Modal

I'm using different forms (POST and GET) in my Django web application and Bootstrap modal to do that.
In my template, user can choose some documents, submit the list of documents which is picked up to a Django form (CustomerForm) in my modal. This CustomerForm lets to send an email with user informations previously filled.
My CustomerForm looks like this :
class CustomerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CustomerForm, self).__init__(*args, **kwargs)
self.fields['country'].empty_label = _('Select a country')
self.fields['country'].queryset = self.fields['country'].queryset.order_by('name')
self.fields['email'].required = True
self.fields['first_name'].required = True
self.fields['last_name'].required = True
self.fields['country'].required = True
self.fields['institution'].required = False
class Meta:
model = Customer
fields = ['email', 'first_name', 'last_name', 'country', 'institution']
widgets = {
'email': forms.TextInput(attrs={'placeholder': _('name#example.com')}),
'first_name': forms.TextInput(attrs={'placeholder': _('First Name')}),
'last_name': forms.TextInput(attrs={'placeholder': _('Last Name')}),
'institution': forms.TextInput(attrs={'placeholder': _('Agency, company, academic or other affiliation')}),
}
I have views.py file :
class HomeView(CreateView, FormView):
""" Render the home page """
template_name = 'index.html'
form_class = CustomerForm
def get_context_data(self, **kwargs):
# display some things
# ...
if "DocumentSelected" in self.request.GET:
checkbox_list = self.request.GET.getlist('DocumentChoice')
document = Document.objects.filter(id__in=checkbox_list)
kwargs['selected_document'] = document
return super(HomeView, self).get_context_data(**kwargs)
def form_valid(self, form):
email = form.cleaned_data['email']
country = form.cleaned_data['country']
for checkbox in self.request.GET.getlist('DocumentChoice'):
document = Document.objects.get(id=checkbox)
token = self.gen_token(email)
now = timezone.now()
expiration = now + settings.DOWNLOAD_VALIDITY
Download.objects.create(email=email, country=country, doc_id=checkbox, token=token,
expiration_date=expiration)
self.send_email(email, document.upload, document.publication.title, token)
return super(HomeView, self).form_valid(form)
And finally in my HTML template you can find something which looks like this :
<form method="GET" action="">
<!-- Table with checkboxes - User has to check wanted objects -->
<div class="row">
<div class="col-md-offset-3 col-md-4">
<input type="submit" class="btn btn-default" name="DocumentSelected" value="{% trans 'Save document(s)' %}"/>
<input type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" value="{% trans 'Send document(s)' %}"/>
</div>
</div>
</form>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{% trans 'Your informations' %}</h4>
</div>
<form method="post" action="" novalidate>
{% csrf_token %}
<div class="modal-body">
<div class="row">
<div class="col-md-12">
{{ form.email|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-6">
{{ form.first_name|as_crispy_field }}
</div>
<div class="col-md-6">
{{ form.last_name|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-6">
{{ form.country|as_crispy_field }}
</div>
<div class="col-md-6">
{{ form.institution|as_crispy_field }}
</div>
</div>
</div>
<div class="modal-header">
<h4 class="modal-title">{% trans 'Your cart' %}</h4>
</div>
<div class="model-body">
{% for element in selected_document|dictsort:'format' %}
<!-- Display wanted objects -->
{% endfor %}
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-default" data-dismiss="modal" value="{% trans 'Send' %}"/>
</div>
</form>
</div>
</div>
</div>
Process :
This is the needed way :
User has to check one or multiple documents
User submits the choice and a modal containing CustomerForm is opening.
User fills CustomerForm fields and see in Cart part his document(s)
User submits the CustomerForm and an email is sent with previous informations/documents.
I think my method could work, but I don't overcome to call form_valid function and I would like to write correctly this class.
There is certainly ugly issues and I apologize by advance. But this is not the best way to improve myself and doesn't reproduce these issues ? ;)
Thanks !
EDIT :
I made something which seems to work. I removed data-dismiss="modal" from my modal submit button. I read that this attribute closed my modal and didn't post any form !
Finally, is it a good way to do what I did ?
Is it possible to replace both buttons Save documents and Send documents by an unique button which get documents and open the modal ?
I made something which seems to work. I removed data-dismiss="modal" from my modal submit button.
Previously :
<input type="submit" class="btn btn-default" data-dismiss="modal" value="{% trans 'Send' %}"/>
Now :
<input type="submit" class="btn btn-default" value="{% trans 'Send' %}"/>
It works now !
It was because data-dismiss="modal" closed the modal and I didn't know that.

Extra form on ModelFormSet

For my Django project, I am rendering the model formset election_formset = modelformset_factory(Election, exclude=('Complete',), formset=BaseElectionFormSet) in my template:
<form method="post" action="">
{{ formset.management_form }}
{% for form in formset %}
<div class='card'>
<div class='card-body w-75 mx-auto'>
<div class='row'>
<div class='col-6 text-center'>
<p>Name<br>{{form.Name}}</p>
</div>
<div class='col-6 text-center'>
<p>Videos<br>{{form.FlipGrid}}</p>
</div>
</div>
<div class='row'>
<div class='col-12 text-center'>
<p>Description<br>{{form.Description}}</p>
</div>
</div>
<div class='row'>
<div class='col-6 text-center'>
<p>Allow registration: {{form.CandidateReg}}</p>
</div>
<div class='col-6 text-center'>
<p>Allow voting: {{form.VotingOpen}}</p>
</div>
</div>
</div>
</div>
{% endfor %}
</form>
When the formset renders, an extra, blank form is shown at the end of the forms. I only want forms to show that are instances of existing records. Why is there an extra blank formset and how can I prevent it?
Try this
election_formset = modelformset_factory(
Election,
exclude=('Complete',),
formset=BaseElectionFormSet,
extra=0
)
The extra keyword defaults to 1 otherwise (see docs):
def modelformset_factory(model, form=ModelForm, formfield_callback=None,
formset=BaseModelFormSet, extra=1, can_delete=False,
can_order=False, max_num=None, fields=None, exclude=None,
widgets=None, validate_max=False, localized_fields=None,
labels=None, help_texts=None, error_messages=None,
min_num=None, validate_min=False, field_classes=None):
Try to use max_num parameter to limit exta if there are some initial data in formset:
election_formset = modelformset_factory(Election, exclude=('Complete',), formset=BaseElectionFormSet, max_num=1)
From the docs:
If the number of items in the initial data exceeds max_num, all initial data forms will be displayed regardless of the value of max_num and no extra forms will be displayed.

Django Form Field Custom attribute assignment and use in template

I am trying to generate a form dynamically and want to assign indentation of form fields. I am trying to assign an custom attribute offset to forms.CharField in subclass. I plan to use this logic to create a form dynamically from an xml file, where the fields would be indented based on the depth of the node.
I am unable to retrieve the value of offset while rendering the template and hence unable to assign the margin-left style parameter. The final html output is also shown.
Can someone please help. I have searched some other answers on this site where it appears that arbitrary attributes can be assigned and retrieved in template. e.g.as in thread here where an arbitrary label_class attribute is assigned
My forms.py file :
class MyCharField(forms.CharField):
def __init__(self, *args, **kwargs):
self.offset = kwargs.pop('offset', 0)
super(MyCharField, self).__init__(*args, **kwargs)
class MyDynamicForm(forms.Form):
def __init__(self, *args, **kwargs):
super(MyDynamicForm, self).__init__(*args, **kwargs)
self.fields["Field_A"] = MyCharField(label="Input A", offset="5")
self.fields["Offset_Field_B"] = MyCharField(label="Input B", offset="50")
My Views.py looks like this:
class MyDynamicView(View):
template_name = 'demo/myform.html'
form_class = MyDynamicForm
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
My template file using bootstrap looks like this:
{% extends 'demo/base.html' %}
{% load bootstrap3 %}
{% block content %}
<form role="form" method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group bootstrap3-required">
<label class="col-md-3 control-label " style = "margin-left: {{field.offset}}px" for="{{ field.name }}">{{ field.label}}</label>
<div class="col-md-9">
<input class="form-control" id="id_{{field.name}}" name="{{ field.name }}" placeholder="{{field.label}}" style="margin-left:{{field.offset}}px" title="" required="" type="text"/>
</div>
</div>
{% endfor %}
{% buttons submit='OK' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
{% endblock %}
The html output is:
<form role="form" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='lTy0rc2r9KNiNNPosUoriUlNzYBpgoVpael1MYLOczFECO7H7LXdES6EGBhUoXx0' />
<div class="form-group bootstrap3-required">
<label class="col-md-3 control-label " style = "margin-left: px" for="Field_A">Input A</label>
<div class="col-md-9">
<input class="form-control" id="id_Field_A" name="Field_A" placeholder="Input A" style="margin-left:px" title="" required="" type="text"/>
</div>
</div>
<div class="form-group bootstrap3-required">
<label class="col-md-3 control-label " style = "margin-left: px" for="Offset_Field_B">Input B</label>
<div class="col-md-9">
<input class="form-control" id="id_Offset_Field_B" name="Offset_Field_B" placeholder="Input B" style="margin-left:px" title="" required="" type="text"/>
</div>
</div>
<div class="form-group"><label class="col-md-3 control-label"> </label><div class="col-md-9"><button class="btn btn-default" type="submit">OK</button> <button class="btn btn-default" type="reset">Cancel</button></div></div>
</form>
It not necessary to instantiate from CharField for that. Probably such initialization of the field in form will be enough for you:
field_a = forms.CharField('Input_A',
widget=forms.TextInput(attrs={'placeholder': 'Input_A', 'style': 'margin-left: 50px'}))

Categories

Resources