I am looking to create a dropdown in a template where the values of the dropdown come from a field (reference) within my Orders model in models.py. I understand creating a dropdown where the values are set statically, but since I am looking to populate with values stored in the DB, I'm unsure of where to start.
I've created the model and attempted playing around with views.py, forms.py and templates. I am able to get each of the order numbers to display but not in a dropdown and I am struggling with how to write my template.
models.py
from django.db import models
class Orders(models.Model):
reference = models.CharField(max_length=50, blank=False)
ultimate_consignee = models.CharField(max_length=500)
ship_to = models.CharField(max_length=500)
def _str_(self):
return self.reference
forms.py
from django import forms
from .models import *
def references():
list_of_references = []
querySet = Orders.objects.all()
for orders in querySet:
list_of_references.append(orders.reference)
return list_of_references
class DropDownMenuReferences(forms.Form):
reference = forms.ChoiceField(choices=[(x) for x in references()])
views.py
def reference_view(request):
if request.method == "POST":
form = references(request.POST)
if form.is_valid():
form.save()
return redirect('index')
else:
form = references()
return render(request, 'proforma_select.html', {'form': form})
proforma_select.html
{% extends 'base.html' %}
{% block body %}
<div class="container">
<form method="POST">
<br>
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label"> {{ field.label }}</label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="button">Add Order</button>
</form>
</div>
{% endblock %}
All I get when I render the template is each of the reference #s listed out but NOT within a dropdown. This leads me to believe my problem is mainly with the template, but I'm unsure as I am new to using Django.
Are you using Materialize CSS? If yes, then Django forms renders dropdowns differently from how Materialize expects them. So you will want to override the form widget. You can do something like so:
forms.py:
class DropDownMenuReferences(forms.Form):
reference = forms.ChoiceField(choices=[(x) for x in references()],
widget=forms.Select(choices=[(x) for x in references()], attrs={'class':
'browser-default'}))
This overrides the parameters passed into html. You can also pass any name tags in the attrs too.
The issue:
https://github.com/Dogfalo/materialize/issues/4904
Related
views.py
def registerPage(request):
form = UserCreateForm()
if request.method=='POST':
form=UserCreateForm(request.POST)
if form.is_valid():
user=form.save(commit=False)
user.save()
return redirect('home')
return render(request,'base/signup.html',{'form':form})
model.py
class User(AbstractUser):
name = models.CharField(max_length=200,null=True)
email = models.EmailField(unique=True,null=True)
bio=models.TextField(null=True)
avatar = models.ImageField(upload_to='images/',null=True)
USERNAME_FIELD='email'
REQUIRED_FIELDS=['username']
forms.py
class UserCreateForm(UserCreationForm):
class Meta:
model = User
fields = ['name','email','password1','password2','bio','avatar']
htmltemplate
{% include 'main.html' %}
{% block content %}
<div>
<form method="POST">
{% csrf_token %}
{% for field in form %}
{{field.label}}
{{field}}
{% endfor %}
<input type="submit" value="Register" >
</form>
</div>
{% endblock content %}
when ever i try to sign up on html template it doesnt work but if i do it in admin panel it works how can i solve it ?
First of all, it is generally not recommended to mess with the default User model from django. Its better to create a Profile model with a OneToOneField relationship with the user.
Other than that, your issue lies with your form. Since you have avatar which is an ImageField you need to change your form in a way that it can accept FILES.
So what you need to do is change your form like this:
<form method="post" action="" enctype="multipart/form-data" >
When you are writing client-side code:
use multipart/form-data when your form includes any <input type="file"> elements.
In order to make your POST request valid, you need to also receive your FILES on your view. That can be done by changing your code to:
if request.method=='POST':
form=UserCreateForm(request.POST, request.FILES)
if form.is_valid():
....
Good day,
I'm trying "create" a DatePicker for one of my Inputfields in Django but it's not working!
In my models.py:
class Customer(models.Model):
...
name = models.CharField()
date = models.DateField()
In my views.py:
def Page(request):
CustomerFormSet = modelformset_factory(Customer, fields='__all__')
formset = CustomerFormSet (queryset=Customer.objects.none())
...
context = {'formset': formset}
return render(request, 'app/base.html', context)
In my template:
{% extends 'app/base.html' %}
{% load widget_tweaks %}
<form actions="" method="POST">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.id }}
...
{% render_field form.name class="form-control" %}
...
{% render_field form.date class="form-control" %}
...
Now my first Inputfield works fine! It returns a fitting Field in Bootstraps "Form-Group"-Layout. But my InputField for Dates remains a simple TextInput with no calendar apearing to choose from.
My Question is: am I doing something wrong or is it still impossible to obtain such a function in this way?
Thanks and a nice evening to all of you.
If you ara using ModelForm try:
from django import forms
class DateInput(forms.DateInput):
input_type = 'date'
class DataTreinoForm(forms.ModelForm):
class Meta:
model = models.YOURMODEL
fields = _all_
widgets = {
'dateField': DateInput
}
The default format is mm/dd/yyyy. I don't know how to change it in this way.
I just solved this too. Add type="date" to the render_field.
{% render_field form.date type="date" class="form-control" %}
You can add any input tag attributes here which is convenient because
Modify form appearance on the template instead of forms.py, which is conceptually consistent
When you save templates, it doesnt reload the app, so faster testing with html
I am trying to save multiple fields of data. I've also changed the database connection from the default sqlite3 to MySQL. And I don't know how to do this
Here's my views.py
def customerview(request):
if request.POST:
form = CustomerForm(request.POST)
if form.is_valid():
if form.save():
return redirect('sales')
else:
return redirect('index')
else:
return redirect('index')
else:
form = CustomerForm
return render(request, 'customer.html', {'form':form})
def salesview(request):
if request.POST:
form = SalesForm(request.POST)
if form.is_valid():
if form.save():
return redirect('index')
else:
return redirect('index')
else:
return redirect('index')
else:
form = SalesForm
data = Customer.objects.latest('id')
return render(request, 'sales.html', {'form':form, 'range':range(data.number_of_transactions)})
Here's my models.py
class Customer(models.Model):
customer_name = models.CharField(max_length=200)
number_of_transactions = models.IntegerField()
class Sales(models.Model):
product_type = models.CharField(max_length=100)
product_code = models.CharField(max_length=100)
product_size = models.CharField(max_length=100)
product_quantity = models.IntegerField()
Here's my brands.html
<form class="form" role="form" action="" method="post"> {% csrf_token %}
{% for i in range %}
<div class="col">
<div class="col-sm-3">
<div class="">
{{ form.product_type | add_class:'form-control' }}
<label for="regular2">Product Type</label>
</div>
</div>
<div class="col-sm-3">
<div class="">
{{ form.product_code | add_class:'form-control' }}
<label for="regular2">Product Code</label>
</div>
</div>
</div>
{% endfor %}
<div class="col-md-12">
<hr>
<div class="card-actionbar-row">
<input type="submit" class="btn btn-flat btn-primary ink-reaction" value="SUBMIT">
</div>
</div>
</form>
The idea is to get the customer details and number of transactions to be performed then that determines the number of fields to be displayed in the sales view. And that works fine.
The problem is to get each of the transactions to be saved in the database. When I submit and check my database tables, only one transaction is saved.
It's clear that you're trying to run before you can walk here.
Firstly, you should concentrate on getting a simple list view to work, without getting confused about the additional complexity involved in displaying a list in a form view. So, make your view inherit from ListView, and remove all the methods. Then fix your template, so that it iterates over stock_list or object_list rather than just stock.
Secondly, once you've got that working, you could try to integrate it with a form. When you do that, learn what methods to override. get_queryset must return a queryset, it should not render a template. In any case, you should almost never need to render a template manually in a class-based view, because the existing logic will do that for you. And if you want to add a queryset to the template context in a create view, for example, you should be overriding get_context_data; which needs to return a dictionary.
Thirdly, if at some point you do need to render a template manually, read the documentation to learn the order of parameters to render: it is request, template_name, context, not as you have it.
I have 2 models in my system:
class Display(models.Model):
name = models.CharField
UE = models.CharField
description
class Register(models.Model):
temp1 = models.FloatField()
temp2 = models.FloatField()
flow = models.FloatField()
I create displays using for inside a template, but the value of each display is a respective field in Register model. I can't make the loop with Register because i use only row (i can't loop fields). Understand?
Take a look of my code:
View:
def main(request):
dp_col = Display.objects.all()
reg = Registers.objects.latest('pk')
context = {
'dp_col': dp_col,
'reg':reg
}
return render(request,'operation.html',context)
Template:
{% for dp in dp_col %}
<div class='col-md-6'>
<div class="display-content">
<div class="display-data">
<h3 class="text-center display-desc">{{dp.name}}
<span>:</span>
<span class="text-center display-value">I need put the value of each field here</span>
<span class='display-unit'> {{dp.UE}}</span>
</h3>
</div>
</div>
</div>
{% empty %}
<!--colocar alguma coisa aqui, caso não tenha nada no for-->
{% endfor %}
Any ideas?
Thanks a lot!
This can be easily solved by using a Django Forms:
yourapp/forms.py
from django import forms
class DisplayForm(forms.ModelForm):
class Meta:
model = Display
fields = '__all__'
yourapp/views.py
from .forms import DisplayForm
def main(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 = DisplayForm(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 = DisplayForm()
return render(request, 'operation.html', {'form': form})
In operations.html:
<form method="post" action="">
{{ form }}
</form>
Or if you want custom html in each field:
<form method="post" action="">
{% for field in form %}
{{ field.label_tag }} {{ field }}
{% endfor %}
</form>
Reference:
https://docs.djangoproject.com/en/1.11/topics/forms/
I have models:
class MediaInfo(models.Model):
title = models.CharField(max_length=50,blank=True)
description = models.CharField(max_length=255,blank=True)
media_file = models.FileField(upload_to=get_upload_file_name)
def __unicode__(self):
return self.title
class Media(models.Model):
media_files = models.ForeignKey(MediaInfo) # I want ManyToManyField but it gives error saying no ForeignKey relation
Here I used Inline Formset to select multiple file.
What I wanted was I wanted a browser button on template and when I click that I could select multiple file or images with all those title and description informations.
For this I wrote a view:
def MediaAddView(request):
MediaInlineFormset = inlineformset_factory(MediaInfo, Media)
if request.method == "POST":
formset = MediaInlineFormset(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return HttpResponseRedirect("someurl")
else:
return render_to_response("media_add.html", {"formset":formset,})
else:
formset = MediaInlineFormset()
return render_to_response("media_add.html", {"formset":formset,})
and my template media_add.html
{% block content %}
<form method="post" action="" enctype="multipart/form-data">{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{form.id}}
<ul>
<li>{{form.media_file}}</li>
</ul>
{% endfor %}
<input type="submit" value="Submit" />
</form>
{% endblock %}
When I do this in my template I see nothing just 3 dots of list (li).
Like I said I wanted a browse button and when I click it I wanted to select and upload multiple files.
Whats wrong in here ? Can anyone guide me ?