Drop down menu from Django database - python

I'd like to create a drop down list in an HTML template that draws data from a Django database. Is there anyway I can code it in the <option value...>?
The examples below work perfectly fine with the databases you create on your own. The problem is, that I need to make use of the username field from django.contrib.auth.models import User.

For example - you have a cars list in Template context. You can do something like this, if I understand you correctly:
<form>
<select name="cars">
{% for car in cars%}
<option value={{ car.name }}>{{ car.name }}</option>
{% endfor %}
</select>
<input type="submit" value="Submit">
</form>

Describe your model and your form as well. It's pretty simple in Django. If you have a form and the form is passed to the template, you can render the form as follows:
{{ form.as_p }}
Model example:
from django.db import models
# Your model choices
class SampleCategory(models.Model):
title = models.CharField(max_length=255)
# Your sample model that uses the model with choices
class SampleModel(models.Model):
category = models.ForeignKey(SampleCategory)
Form example:
from django import forms
from yourapp.models import SampleModel
class SampleModelForm(forms.ModelForm):
class Meta:
model = SampleModel

Related

Django-filter AND Django-tables2 CheckBoxColumn compatibility

I want to have a checkboxcolumn in my returned table via Django-filter, then select certain rows via checkbox, and then do something with these rows.
This is Django-filter: django-filter.readthedocs.io/en/1.1.0 This is an example of checkboxcolumn being used in Django-tables2: stackoverflow.com/questions/10850316/…
My question is: can I use the checkboxcolumn for a table returned via Django-filter?
Thanks
Full working code:
filters.py:
from project_django.models import SomeModel
import django_filters
class UserFilter(django_filters.FilterSet):
class Meta:
model = SomeModel
fields = ['jobnumber', ]
views.py:
def custom_table(request):
user_list = SomeModel.objects.all()
data = request.GET.copy()
if len(data) == 0:
data['jobnumber'] = 0
user_filter = UserFilter(data, queryset=user_list)
table1 = JobTable(user_filter.qs)
# WORKING: custom table with checkbox
RequestConfig(request).configure(table1)
# WORKING: custom table with checkbox
return render(request, 'index.html', {'table1': table1, 'filter': user_filter})
tables.py:
import django_tables2 as tables
from .models import SomeModel
class JobTable(tables.Table):
selection = tables.CheckBoxColumn(accessor='pk')
#jobnumber = tables.Column()
class Meta:
model = SomeModel
index.html:
{% load widget_tweaks %}
{% block content %}
<form method="get">
<div class="well">
<h4 style="margin-top: 0">Filter</h4>
<div class="row">
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.as_p }}
<button type="submit">Search</button>
</div>
</div>
</div>
</div>
</form>
<form action="roll.html" method="post">
{% render_table table1 %}
<input type="submit">
</form>
What django-filter does from the perspective of django-tables2 is supplying a different (filtered) queryset. django-tables2 does not care about who composed the queryset, it will just iterate over it and render rows using the models form the queryset.
So if you a checkbox column to the table or not, or use django-filter or not, django-tables2 will just render any queryset it gets.
If you want to use the checked records for some custom filter, you'll have to do some manual coding, it's not supported out of the box.
Short answer: yes, you can use django-tables2 with a CheckboxColumn together with django-filter.

can't set radio button to required in django

I have the following radio button html using django widget tweaks (i do not have to use this library and open to using whatever method works):
{% for choice in seeking_form2.disaster_recovery %}
<div class="radio radio-primary radio-inline">
{{ choice.tag|attr:"required" }}
<label for='{{ seeking_form2.disaster_recovery.auto_id }}_{{ forloop.counter0 }}'>{{ choice.choice_label }}</label>
</div>
{% endfor %}
Which should create radios that look like this:
<input id="id_disaster_recovery" name="disaster_recovery" type="radio" value="2" required>
My model looks like:
BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
disaster_recovery = models.BooleanField(choices=BOOL_CHOICES, default=False, )
My form looks like:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'disaster_recovery': forms.RadioSelect(),
}
I get the error:
'SafeText' object has no attribute 'as_widget'
If i understand your problem correctly, you should be overriding this in the form, rather than at the template, or the models.
class MyModelForm(..):
disaster_recovery = forms.ChoiceField(choices=BOOL_CHOICES, widget=forms.RadioSelect(), required=True) #Default is dropdown
Now, you could simplify your HTML to render the radiobuttons.
Some more context on this can be found here
To add the HTML required attribute, to your existing form, you can do:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'disaster_recovery': forms.RadioSelect(attrs={"required": "required"}),
}
Here is the relevant documentation on the custom attributes

Rendering django model validation error in template

I am building a web application on django. As part of this, I have created one html form like following:
<form method="post" action="/voting/add_state/">{% csrf_token %}
State name:<br>
<input type="text" name="state_name"><br>
<input type="submit" value="Submit">
</form>
In models.py I have added unique constraint validation on name like following:
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
So for duplicate name, it throws a unique constraint error which I would like to capture in the template. Can anyone please give any suggestion.
Create a form based on your model
#forms.py
from django import forms
from .models import State
class StateForm(forms.ModelForm):
class Meta:
model = State
fields = ('name',)
now use this form on your views
#views.py
from django.views.generic import FormView
from .forms import StateForm
class MyView(FormView):
template_name = 'template.html'
form_class = StateForm
success_url = '/my-url-to-redirect-after-submit/'
template.html
<form method="post">
{% csrf_token %}
Name
{{ form.name }}
{{ form.name.errors }}
<input type="submit" value="Create">
</form>
Django has Form processing built in. Django has "Model Forms", which automatically render the form for your model. If you pass it through the view and reference it in the context it will automatically generate the html for you, but if you would like more control over what is rendered in the template then you can reference the form attributes that Django Model Form produces.
I strongly suggest working within the framework Django provides to you for building forms; it provides a lot of boilerplate code for building, validating and abstracting forms and is especially competent for simple forms like these.
Here is an example:
models.py
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
forms.py
class StateForm(forms.ModelForm):
model = State
fields = (name,)
views.py
from django.views.generic.edit import FormView
class StateForm(FormView):
template_name = 'state_form.html'
form_class = StateForm
success_url = '/thanks/'
state_form.html (example of auto generated form)
{{ form }}
state_form.html (example of custom form)
<form action="/" method="post">
{% csrf_token %}
{{ form.errors }}
{% for field in form %}
<input type="{{ field.type }}" name='{{ field.name }}' class="submit" value="{{ field.value}}">
{% endfor %}
<input type="submit" name='submit" value="Submit">
</form>
References:
Django Forms:
https://docs.djangoproject.com/en/1.9/topics/forms/
Django Model Forms: https://docs.djangoproject.com/en/1.9/topics/forms/modelforms/
Django Generic Views:
https://docs.djangoproject.com/en/1.9/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView
You could create a form for State model and create the validator, so if the user try with a duplicate name, the form raise a message something like this:
models.py
class State(models.Model):
name = models.CharField(max_length=200, unique=True)
vote_counted = models.BooleanField(default=False)
forms.py
def unique_name(value):
exist = State.objects.filter(name=value)
if exist:
raise ValidationError(u"A state with the name %s already exist" % value)
class StateForm(forms.Form):
name = forms.CharField(label=('Name:'), validators=[unique_name])
Then you just need to render the StateForm in the template.

Django:how to make the dynamic drop down list based on Another app's table

I have two apps, the App1 contains the value "Region"(with duplicate), in App2, I want to base on the distinct "Region" Value to show the drop down list.
App 1 model.py:
class A(models.Model):
Region=models.CharField(verbose_name='Region',max_length=10,blank=True)
......
App 2 model.py:
from django import forms
from django.forms import ModelForm
from django.db import models
from django.contrib import dupont
class input(models.Model):
Region=models.CharField(max_length=100)
APP 2 Forms.py
from django import forms
from django.forms import ModelForm
from .models import input
from dupont.models import A /*Here I want to import the class from the 1st App
from django.contrib.auth.models import User
import Queue
class inputform(forms.ModelForm):
regionlist = forms.ChoiceField(label=u'Region',choices=())
def __init__(self,*args,**kwargs):
super(inputform,self).__init__(*args,**kwargs)
self.fields['regionlist'].choices=((x.que,x.disr) for x in dupont.objects.values('Region').distinct())
*/*Above code is to make the dynamic drop down list, based on the 1st App's table, and only use the distinct value from the column "Region", but it seems the query is not correct.
Error here shows:'dict' object has no attribute 'que'*
class Meta:
model = input
fields = ('Region')
App2 html:
<form action="" method="post">{% csrf_token %}
<select name="">
{% for val,name in form.choice_filed.choices %}
<option value="{{ val }}" {% ifequal data.val val %}selected {% endifequal %}>
{% endfor %}
</select> /* here is to show the drop down list from app2
<div class="fieldWrapper">
<p><input type="submit" value="Submit" />p>div>
</form>
The error code at present is :'dict' object has no attribute 'que' to that drop down list code line.
dupont.objects.values('Region') returns a list of dictionaries.

Django crispy forms shows password as clear text

Crispy forms currently shows my password field as clear text. I have tried the following but I still cannot get it to use type=password.
Fieldset(
'Enter a password.',
PrependedText('password', '<i class="fa fa-key"></i>',
placeholder='Password',
autocomplete='off',
widget=forms.PasswordInput,
),
),
I have also tired type="password" with no effect.
I get no error.
I'm 99.9% positive that you missed adding the widget to the form field declaration. You should have something like this in order to display a password field:
class MyForm(forms.Form):
...
password = forms.CharField(widget=forms.PasswordInput)
...
And the layout should be as simple as:
Layout(
PrependedText('password', '#', placeholder="password", autocomplete='off')
)
The widget= keyword argument is defined on the Django's forms.CharField constructor and not on the django-cryspy-forms' bootstrap.PrependedText constructor.
You can find more information on Django forms fields here.
UPDATE
If you have a model form, it's being constructed from your model, either automatically (eg using the admin views), by using modelform_factory or by defining the ModelForm yourself. Here is an example of the 3rd approach.
class MyModelForm(forms.ModelForm):
class Meta:
fields = (... fields you want to include in the form ...)
password = forms.CharField(widget=forms.PasswordInput, ...)
Please note that by providing your model form field override, you'll have to also provide attributes like label, help_text (and such) because they will not be automatically copied from the model field.
I never had good luck with crispy-forms and formsets, so I just use forms directly in templates. See if that works:
<form method="post">{% csrf_token %}
{{ formset.management_form|crispy }}
{% for form in formset %}
<input id="id_form-{{ forloop.counter0 }}-id" name="form-{{ forloop.counter0 }}-id" type="hidden" value="{{ form.instance.pk }}"/>
{{ form|crispy }}
{% endfor %}
</form>
You need to define PasswordInput.
class YourForm(forms.ModelForm):
password = forms.CharField(label='Enter Password',widget=forms.PasswordInput(attrs={'placeholder': 'alphanumeric password'}))

Categories