Django Formsets rendering fields manually - django

I am trying to render fields manually in django formset.
<select class="form-control" id="{{ line_form.label.id_for_label }}" name="{{ line_form.label.name }}">
{% if form.label.value %}
<option value="{{ form.label.value }}">{{ form.label.value }}</option>
{% else %}
<option value="" selected>-</option>
{% endif %}
{% for item in view.items %}
<option value="{{item.id}}">{{item.name}}</option>
{% endfor %}
</select>
The name of the above field is label but i want it to lines-0-label. When i add a new form in the formset the above field has the same name it should be lines-1-label, and should increase so on. i.e., lines-2-label, lines-3-label, lines-4-label, ...., lines-101-label.
views.py
class InvoiceCreateView(generic.CreateView):
template_name = "books/invoice_create_or_update.html"
model = Invoice
form_class = InvoiceForm
formset_class = InvoiceLineFormSet
success_url = reverse_lazy("books:invoice-list")

Related

django Form values are empty

I have a problem with the home page displaying form values. Although on the search page the values are fine. What could be the problem here? I copied the same form from the search page to the homepage but still, it doesn't work, the values are empty. Any hint is appreciated, thank you!
search page:
<form action="{% url 'search' %}">
<div class='flx around px'>
<input type='text' id='search-keyword' class='search-keyword form-control'
placeholder='keywords (pool,garage)'>
<select name='area' id='search-area' class='form-control'>
<option selected="true" disabled="disabled" selected>Area(All)</option>
{% for key,value in area_choices.items %}
<option value="{{ key }}" {% if key == values.area %} selected {% endif %}>{{ value }}</option>
{% endfor%}
</select>
</div>
<div class='flx around'>
<select name="bedrooms" class="form-control">
<option selected="true" disabled="disabled" selected>Bedrooms(All)</option>
{% for key,value in bedroom_choices.items %}
<option value = "{{ key }}"
{% if key == values.bedrooms %}
selected
{% endif %}
>{{ value }}</option>
{% endfor %}
</select>
<select name="price" class="form-control ">
<option selected="true" disabled="disabled" selected>Price(All)</option>
{% for key,value in price_choices.items %}
<option value = "{{ key }}"
{% if key == values.price %}
selected
{% endif %}
>{{ value }}</option>
{% endfor %}
</select>
</div>
<button type = "submit" class='btn fntmk my2 size'>Search <i class="fas fa-search size"></i></button>
</form>
home page:
<form action="{% url 'search' %}">
<div class = 'flx around px iphone'>
<input name = 'keywords' type = 'text' id = 'search-keyword' class = 'search-keyword form-control' placeholder = 'keywords (pool, garage)'>
<select name = 'area' id = 'search-area' class = 'form-control'>
{% for key,value in area_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
</div>
<div class = 'flx around iphone'>
<select name="bedrooms" class="form-control">
<option selected="true" disabled="disabled" selected>Bedrooms(All)</option>
{% for key,value in bedroom_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
<select name="price" class="form-control ">
<option selected="true" disabled="disabled" selected>Price(All)</option>
{% for key,value in price_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
</div>
<button type = "submit" class = 'btn fntmk my2 size'>Search <i class="fas fa-search size"></i></button>
</form>
view:
from .choices import price_choices, bedroom_choices, area_choices
def search(request):
queryset_list = Oglas.objects.order_by('-list_date')
# keywords
if 'keywords' in request.GET:
keywords = request.GET['keywords']
if keywords:
queryset_list = queryset_list.filter(description__icontains = keywords)
# Area
if 'area' in request.GET:
area = request.GET['area']
if area:
queryset_list = queryset_list.filter(area__iexact = area)
# rooms
if 'bedrooms' in request.GET:
bedrooms = request.GET['bedrooms']
if bedrooms:
queryset_list = queryset_list.filter(bedrooms__lte=bedrooms)
# price
if 'price' in request.GET:
price = request.GET['price']
if price:
queryset_list = queryset_list.filter(price__lte = price)
context = {
'area_choices' : area_choices,
'bedroom_choices' : bedroom_choices,
'price_choices' : price_choices,
'listings' : queryset_list,
'values' : request.GET,
}
return render(request, 'pages/search.html', context)
Form are handled completly different. You're mixing up the template with the form handling.
Have a look in the doc first. You need to add a form object into your context.
Extract from the mentioned doc:
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})

How to get selected value from drodown of parent template in to the view in Django where template inheritance is used

Just started learning Django where I faced this problem
I want to create eCommerce site where users can select their location(Like State & Area) and accordingly the products will be displayed to do this I have already created two drop downs in the navbar.html which is extended by the base.html which is extended by the home.html.
cart_template_tags.py:
register = template.Library()
#register.filter
def load_city(request):
locations = Locations.objects.filter()
return locations
#register.filter
def load_areas(request):
locations = Area.objects.filter()
return locations
navbar.html:
{% load cart_template_tags %}
<form method="GET" action=".">
<ul class="navbar-nav nav-flex-icons">
<select id="city" class="form-control" name="city">
<option selected>city...</option>
{% for cityVal in request.user|load_city %}
<option value="{{ cityVal }}">{{ cityVal }}</option>
{% endfor %}
</select>
<select id="area" class="form-control" name="area">
<option selected>area...</option>
{% for areaVal in request.user|load_areas %}
<option value="{{ areaVal }}">{{ areaVal }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-primary">Search</button>
</form>
I have displayed products using home view where I rendered home.html
Views.py
class HomeView(ListView):
model = Item
paginate_by = 10
template_name = "home.html"
how can I get the value which I have selected in drop down "city" & "area" in HomeView ?
If you have any suggestion please suggest or if you know any opensource code where this functionality (Location wise product display) is developed you can suggest that too

How to render Django model form drop down manually in the template?

Here is my model form
class CategoryCreateForm(forms.ModelForm):
class Meta:
model = Category
fields = [
'nature',
'name',
'description',
]
The field nature is a one-to-many foreign field (There could be many categories of the same nature). I know I can render this field in the template using {{ form.nature }} but I would like to render the form manually without the help of Django or crispy forms. I have managed to do so for the other fields but don't know how to do it for a select field of a model form. I am looking for a solution similar to the following
<select class="custom-select custom-select-sm{% if form.nature.errors %} is-invalid{% endif %}" id="{{ form.nature.id_for_label }}" name="{{ form.nature.html_name }}">
{% for nature in form.nature.objects %}
<option value="{{ nature.id }}">{{ nature.name }}</option>
{% endfor %}
</select>
This is what worked
<select class="custom-select custom-select-sm{% if form.nature.errors %} is-invalid{% endif %}" id="{{ form.nature.id_for_label }}" name="{{ form.nature.html_name }}">
{% for id, name in form.fields.nature.choices %}
<option value="{{ id }}">{{ name }}</option>
{% endfor %}
</select>

Update / edit django object after selecting it from a dropdown list

I want to update / edit a product from a page by clicking a form button (UPDATE) after selecting product from a dropdown list or an auto-complete list.
List.html page works fine while clicking on UPDATE button update.html page cannot parse the POST data.
Manually I could access update.html with pk suffix (/update/1/), it is working fine too.
How can I pass pk's value alone to url?
views.py
class ProductUpdateView(UpdateView):
template_name = 'update.html'
model = Product
fields = ['name', 'description', 'image', 'file',]
success_url = '/list/'
class ProductsView(ListView,):
template_name = 'list.html'
model = Product
urls.py
urlpatterns = [
url(r'^list/$', ProductsView.as_view(), name='list'),
url(r'^update/(?P<pk>[0-9]+)/$', ProductUpdateView.as_view(), name='update'),
]
list.html
<body>
<form method='POST' action='/update/'> {% csrf_token %}
<select name='pk'>
{% for obj in object_list %}
<option value='{{ obj.id }}'>{{ obj.name }}</option>
{% endfor %}
</select>
<input type="submit" value='UPDATE'>
</form>
</body>
You can do this by only using <select>
<select name="select_path" id="select_path"
ONCHANGE="location = this.options[this.selectedIndex].value;">
{% for obj in object_list %}
<option value="{% url app_name:update obj.id %}">{{ obj.name }}
</option>
{% endfor %}
</select>
You just need to change the option value, I don't know the exact url, tewak as per your requirement.
I know it's a little bit late but this answer will definitely help someone.
<select name="select_path" id="select_path">
<option value="{{ initial_value }}">{{ initial_value name }}</option>
{% for obj in object_list %}
<option value="{{ edited object value }}">{{ edited obj.name }}
</option>
{% endfor %}
</select>
Get the value normally as you would when saving a form.

Extra chars in django template

I've some code like this:
<select id="form.category}}">
{% for category in form.category %}
<option value="{{ category }}"></option>
{% endfor %}
</select>
And result is:
https://zapodaj.net/940329c1516df.png.html
Why?
#edit
category = models.CharField(max_length=100, choices=get_categories())
def get_categories():
categories = (
("wydarzenia", "wydarzenia"),
("informacje", "informacje"),
("konkursy", "konkursy"),
("wycieczki", "wycieczki"),
("sport", "sport"),)
return categories
form.category is a field in model
The option looks empty because you are not showing anything inside the options tag. You need to display some labels for option tag. Do something like this if category is an object and it has attributes like id and name.
<select id="form.category">
{% for category in form.category %}
<option value="{{ category.id }}">{{category.name}}</option>
{% endfor %}
</select>
If category is a string or number do something like this
<select id="form.category">
{% for category in form.category %}
<option value="{{ category }}">{{category}}</option>
{% endfor %}
</select>
Bear in mind that form.category should be an iterable.