How to get Option field value in Request in Django? - python

I am trying to update my foem, and I have Country value in dropdown and I want to get this value in request, so that i can update my form using this value in request, Please check my code and let me know where I am mistaking.
Here is my test.html file...
<select name='country'>
<option>Select One</option>
{% for countries in country %}
<option value="{{country.id}}" {% if countries.id == datas.country_id %}selected{% endif
%}>{{countries.country}}</option>
{% endfor %}
</select>
here is my views.py file...
datas = MyModelName.objects.get(pk=id)
if request.method == "POST"
datas.country = request.POST.get('country')
datas.save()
it's not selecting the country, it's giving me error, Please guide me how i can solve this issue.

you better use ModelForm to edit data in your models, it allows you to check all entered values in more clean way
create ModelForm to edit your data
class MyModelNameEditForm(forms.ModelForm):
class Meta:
model = MyModelName
then in your views.py you can do this:
datas = MyModelName.objects.get(pk=id)
if request.POST:
edit_form = MyModelNameEditForm(request.POST, instance=datas)
if edit_form.is_valid():
edit_form.check()
else:
edit_form = MyModelNameEditForm(instance=datas)
# don't forget to send your form as a parameter to your template
return render(request, "path_to_template/test.html", {'edit_form': edit_form})
then in your test.html you can replace:
<select name='country'>
<option>Select One</option>
{% for countries in country %}
<option value="{{country.id}}" {% if countries.id == datas.country_id %}selected{% endif
%}>{{countries.country}}</option>
{% endfor %}
</select>
with one line
{{ edit_form.country }}
you can read more about ModelForm in official docs https://docs.djangoproject.com/en/3.1/topics/forms/modelforms/#modelform

Related

How to solve blank page after posting the form problem?

I want to send a basic form to views. I create everything that it need but when I submit the post, it doesn't send a return a blank page.
This is my form and app:reports is the same page with form, because I want to return the same page. I need the values of year_one and year_two.
<form method="post" action="{% url 'app:reports' %}">
{% csrf_token %}
<label for="year_one">Select year 1:</label>
<select id="year_one" name="year_one">
{% for case in query_trend %}
<option value="{{case.date_created__year}}" >{{case.date_created__year}}</option>
{% endfor %}
</select>
<label for="year_two">Select year 2:</label>
<select id="year_two" name="year_two">
{% for case in query_trend %}
<option value="{{case.date_created__year}}">{{case.date_created__year}}</option>
{% endfor %}
</select>
<button onclick="test()">click</button>
</form>
And this is my view
if self.request.method == 'POST':
year_one = self.request.GET.get('year_one')
year_two = self.request.GET.get('year_two')
return HttpResponseRedirect('fdm:outstanding_reports')
What should I do for using these values in views?
Assuming your button's test() method is successfully submitting the form...If you are passing the request to your view,ie,
def reports(request):
Then you can refer to the posted values of year_one and year_two as:
if request.method == 'POST':
year_one = request.POST.get('year_one')
year_two = request.POST.get('year_two')
(GET is when you send values contained in the URL, eg page?year_1=1975&year_2=1300, POST is when it happens in the background. A form will generally use only one or the other, so you your version probably wasn't getting any values. Confusingly, you also use the lowercase '.get()' to retrieve the POST values)

How do i save/show manytomany field in select option field

I am working on a project where users can upload a post, edit a post and tag other users. I was able to implement upload post, edit and tag users (I implemented tag users with jquery ui). When i want to edit a post i have already tagged users on, i do not get the names of the users on select option field, instead it shows empty. How do i save/show users already tagged users from manytomany field in select option field in template. I will attach images to my question for clarity.
These are the users i tagged on my post, showing in manytomany field:
This image below is what i want, when i want to edit my post, let all tagged users of that post be shown in select option field:
Views.py:
def update_post_view(request, id):
#update post
post = get_object_or_404(Post, id=id)
edit_form = PostForm(request.POST, instance=post)
if request.method == "POST":
if edit_form.is_valid():
edit_form.save()
return redirect('site:comments', id=id)
else:
edit_form = PostForm(instance=post)
#Tag username dropdown in form
tag_list_users = User.objects.all()
context = {
'edit_form': edit_form,
'post':post,
'tag_list_users': tag_list_users,
}
return render(request, 'update_post.html', context)
Template:
<label for="id_tag_someone">Tag someone:</label><br>
<select name="tag_someone" id="id_tag_someone" multiple="" class="chosen w-100">
{% for user in tag_list_users %}
<option value="{{user.pk}}">{{user}}</option>
{% endfor %}
</select>
jQuery:
$('.chosen').chosen();
I was able to get this working by adding code to my views and template:
Views.py
#tagged_users is a related_name to tag someone in Model
tagged_user = User.objects.filter(tagged_users=post)
Template
<label for="id_tag_someone">Tag someone:</label><br>
<select name="tag_someone" id="id_tag_someone" multiple="" class="chosen w-100">
{% for user in tagged_users %}
<option value="{{user.pk}}">{{user}}</option>
{% endfor %}
{% for user in tag_list_users %}
<option value="{{user.pk}}">{{user}}</option>
{% endfor %}
</select>

Django dropdown is not populated

I want my dropdown to get populated with values from one of my db tables in my Django project, yet it remains blank and I can't figure out why.
This is my html code of my home.html page:
<select name="regions" id="regions">
{% for item in regions_list %}
<option val="{{ item.name_reg }}"> {{ item.name_reg }} </option>
{% endfor %}
</select>
models.py:
class data_reg(models.Model):
id = models.AutoField(primary_key=True)
name_reg = models.TextField(db_column='NAME_REG', blank=True, null=True)
class Meta:
managed = True
db_table = 'reg'
views.py:
def MyView(request):
regions_list = RegionChoiceField()
query_results_dict = {
'regions_list': regions_list,
}
return render(request,'home.html', query_results_dict)
forms.py:
class RegionChoiceField(forms.Form):
regions = forms.ModelChoiceField(
queryset=data_immo.objects.values_list("name_reg", flat=True).distinct(),
empty_label=None
)
when passing ModelChoiceField to context I think the template should be different.
{% for item in regions_list %}
<option val="{{ item.name_reg }}"> {{ item.name_reg }} </option>
{% endfor %}
change to
{% for item in regions_list %}
{{ item }}
{% endfor %}
or even simpler, just put your form in the template
{{regions_list}}
Hope this works,
Greeting
Ken
I just tested this and it seems to work for me.
Can you print the query in your forms.py
print(data_immo.objects.values_list("name_reg", flat=True).distinct())
This will show the query set in your terminal:
<QuerySet ['a_value']>
I find it always good to print at various levels for debugging, fast and easy.
I managed to make it work and did it by avoiding using forms.py. I simply generated my 'regions_list' variable directly in views.py and only after that it managed to get properly recognized. So this is how it finally looked like:
def MyView(request):
regions_list = data_immo.objects.values_list("name_reg", flat=True).distinct()
query_results_dict = {
'regions_list': regions_list,
}
return render(request,'home.html', query_results_dict)
Also, I amended my html code slightly, as per Ken's suggestion:
<select name="regions" id="regions">
{% for item in regions_list %}
<option val="{{ item.name_reg }}"> {{ item}} </option>
{% endfor %}
</select>

HTML tags for choicefield in Django

I cant seem to find ANYWHERE on how to do choicefield HTML tags in Django. I found radio buttons and other advance choice fields, but nothing on basic drop down HTML tags with Django. I have models.py and view.py set up passing list1 to the html pages, but cant seem to make it display anything except
<select style="width:300px">
{% for choice in list1.VIEWS %}
<option>{{choice}}</option>
{{choice}}
{% endfor %}
</select>
Help would be greatly appreciated
models.py
class preset_list(models.Model):
VIEWS = (
('1', 'X'),
('2', 'Y'),
)
query_choice = forms.ChoiceField(choices=VIEWS)
view.py
list1 = models.preset_list()
return render_to_response('services.html',
{'array':json.dumps(data, cls=SpecialEncoder),
'list1':list1},
)
ModelForms are your friend here.
models.py
class PresetList(models.Model):
VIEWS = (
('1', 'X'),
('2', 'Y'),
)
query_choice = forms.ChoiceField(choices=VIEWS)
forms.py
from django.forms import ModelForm
from . import models
class PresetListForm(ModelForm):
class Meta:
model = models.PresetList
view.py
from . import forms
def my_view(request):
preset_form = forms.PresetListForm()
return render_to_response('services.html', {
'array': json.dumps(data, cls=SpecialEncoder),
'preset_form': preset_form,
})
services.html
<form method=POST action="/somewhere">
{{ preset_form.as_p }}
</form>
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
https://docs.djangoproject.com/en/1.6/ref/forms/fields/#choicefield
Give the generic CreateView a try.
views.py
from django.views.generic.edit import CreateView
from .models import PresetList
class PresetListCreate(CreateView):
model = PresetList
presetlist_form.html
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>
we can use this without using django form
<select style="width:300px" name="presen">
{% for val, name in preset_list.VIEWS %}
<option value="{{val}}">{{name}}</option>
{% endfor %}
</select>
Not sure what you want done, but if you eant to send 1 when X is displayed, the following should work:
<select style="width:300px">
{% for choice in list1.VIEWS %}
<option value={{choice.0}}>{{choice.1}}</option>
{{choice}}
{% endfor %}
</select>
You can create a form with a drop-down and tell it which values to populate it with like so:
Form
class MyDropDownForm(forms.ModelForm):
somerow = forms.ModelChoiceField(
# change this queryset if you want to limit the options
queryset= MyModel.objects.all().values('somerow'),
widget=Select(),
required=True,
)
class Meta:
model = MyModel
fields = ['somerow']
View
class MyView(DjangoTemplateView):
def get(self, request):
# you can set an instance when creating the form to set the value
# to be that of an existing row in your model
# MyDropDownForm(instance=MyModel.objects.filter(id=1))
form = MyDropDownForm()
return render_to_response('app/page.html', {'form': form})
def post(self, request):
# if you had set the instance in the get you want to do that again
form = MyDropDownForm(data=request.POST)
if form.is_valid():
return render_to_response('app/success.html')
return render_to_response('app/page.html', {'form': form})
Page.html
<form method="post">
{% csrf_token %}
{{ form.id }}
{{ form.myrow }}
{% if form.myrow.errors %}
{% for error in form.myrow.errors %}<p>{{ error }}</p>{% endfor %}
{% endif %}
<button>Submit</button>
</form>
Take a look at the docs here for more info on creating model forms.

django ModelForm save issue with ManyToManyField

I'm new to Django and was needing some help on a view error i am getting.
I wrote a view that will display a data table of "Groups" if the request method is GET, or display a form to edit a particular "Group" if the request method is POST (item to edit is passed with POST data).
Also, if POST on an existing item, i'd like the form to be pre-populated with the data i already have in the table for that item. I've pretty much got it all down, except when i goto save an edited form, i keep getting this error:
"Cannot set values on a ManyToManyField which specifies an intermediary model"
Any help would be greatly appreciated. Also, I'm new to all this web dev stuff, so if i'm doing something completely silly or am missing a concept, please feel free to flame me accordingly. ;-)
Model
class Alias(models.Model):
def __unicode__(self):
return unicode(self.alias)
alias = models.CharField(max_length=32)
class Octet(models.Model):
def __unicode__(self):
return unicode(self.num)
num = models.IntegerField(max_length=3)
class Group(models.Model):
def __unicode__(self):
return unicode(self.name)
name = models.CharField(max_length=32) #name of the group
id = models.AutoField(primary_key=True) #primary key
octets = models.ManyToManyField(Octet, through='OctetAssignment', blank=True) #not required
aliases = models.ManyToManyField(Alias, through='AliasAssignment', blank=True) #not required
class OctetAssignment(models.Model):
octet = models.ForeignKey(Octet) #octet
group = models.ForeignKey(Group) #group that octet is assigned to
class AliasAssignment(models.Model):
alias = models.ForeignKey(Alias)
group = models.ForeignKey(Group)
View
def index(request):
if request.method == 'GET':
groups = Group.objects.all().order_by('name')
return render_to_response('groups.html',
{ 'groups': groups, },
context_instance = RequestContext(request),
)
elif request.method == "POST":
g = Group.objects.get(id=request.POST['id'])
form = GroupEditForm(instance=g)
return render_to_response('groups.html',
{ 'form': form, },
context_instance = RequestContext(request),
)
def save(request):
if request.method == "POST":
form = GroupEditForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/tradedesk/groups/') # Redirect after POST
To make it complete, here is the form template code i'm using that renders the table and edit page.
Template
<h1>Group Information</h1>
{% if groups %}
<table border=1>
{% for group in groups %}
<tr>
<td>{{group.name}}</td>
<td>{% for octet in group.octets.all %} {{octet}} {% endfor %}</td>
<td>{% for alias in group.aliases.all %} {{alias}} {% endfor %}</td>
<td>{{group.analyst}}</td>
</tr>
{% endfor %}
</table>
<br></br>
<form method="post" action="/groups/">{% csrf_token %}
<select name="id" >
{% for group in groups %}
<option value="{{group.id}}">{{group.name}}</option>
{% endfor %}
</select>
<input type="submit" value="Edit">
</form>
{% endif %}
{% if form %}
<form method="post" action="/groups/save/">{% csrf_token %}
{{form}}
<br></br>
<input type="submit" value="Save">
<form>
{% endif %}
</div>
Try to remove the intermediary models OctetAssignment and AliasAssignment. They should be used only when you want to add custom fields to them. Otherwise Django creates them and uses them transparently by itself.

Categories

Resources