I'm trying to create a drop-down list of member IDs for users to choose from. I created a form called SelectForm in forms.py:
from .models import Member
from django import forms
class MemberForm(forms.ModelForm):
class Meta:
model = Member
fields = '__all__'
class SelectForm(forms.Form):
memberid = forms.ModelChoiceField(queryset=Member.objects.values_list('member_id', flat=True))
With the view:
class SelectView(generic.ListView):
template_name = 'expcore/select_member.html'
model = Member
def select_member(request):
form = SelectForm()
if request.method == 'POST':
form = SelectForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/questions/')
else:
form = SelectForm()
return render(request, 'select_member.html', {'form': form})
Right now, all the HTML gives me is 'Member Selection: Please blablablabla' with a LIST of bullet points that correspond to the number of existing member IDs. However, the actual member IDs don't show up; furthermore, the whole thing is in a list format right now and not a drop-down menu, which I want.
select_member.html:
{% load staticfiles %}
<title>Member Selection</title>
<h1>Member Selection</h1>
Please select your Member ID from the drop-down menu.
<ul>
{% for member_id in object_list %}
<li><a href='/member/{{ member.name }}'></a></li>
{% empty %}
<li>None available.</li>
{% endfor %}
</ul>
I believe the form I created is supposed to generate a drop-down menu for me but I don't think I'm getting the view/HTML right. Can you guys help me out?
Also - member IDs is under the class Member in my models.py:
class Member(models.Model):
member_id = models.SlugField(max_length=10)
def __str__(self):
return self.name
Thank you.
Please take a look at this third party application: django-crispy-forms. It will make your life way easier.
In your template:
{% load staticfiles %}
<title>Member Selection</title>
<h1>Member Selection</h1>
Please select your Member ID from the drop-down menu.
<!-- Form -->
<form method="POST" action="your_view">
{{ form }}
</form
<ul>
{% for member_id in object_list %}
<li><a href='/member/{{ member.name }}'></a></li>
{% empty %}
<li>None available.</li>
{% endfor %}
</ul>
Related
I've menaged to create a form that allow me to save my website user information in the database. Right now I'd like to create a page where the saved info are showed to my user also. Of course I want my user to be able to see only their own information. This is what I came up with until now, it doesn't wotk and unfortunly I'm not getting any error, just a blanck html page aside for the title. How can I solve this? Thank you all!
model.py
class Info(models.Model):
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
phone = models.CharField(max_length=10)
views.py
def show(request):
info = Info.objects.all().filter(first_name=request.user)
return render(request, 'profile/show.html', {'info': info})
info.html
<h1> Profile </h1>
</br></br>
{% if user.is_authenticated %}
{% for info in info %}
<li>First Name: {{ info.first_name }}</li>
<li>Last Name: {{ info.last_name }}</li>
<li>Phone Number: {{ info.phone }}</li>
{% endfor %}
{% endif %}
request.user type is User. So when you are passing it to first_name, doesn't seem right
You can do the followings:
def show(request):
user_first_name = request.user.first_name
info = Info.objects.all().filter(first_name=user_first_name)
return render(request, 'profile/show.html', {'info': info})
The filter method apply on queryset in Django return a list not an single object.
You can fix your issue like this :
def show(request):
# You can use id to get a single user like bellow
info_id = Info.objects.get(user_id=request.user.id)
# Or use the `first` method of queryset to retrieve the first element in the list
info_name = Info.objects.all().filter(first_name=request.user.first_name).first()
return render(request, 'profile/show.html', {'info': info})
So I wrote a small shopping list application using Django. Users may enter their desired items which are stored in a database alongside a category they reside in to make the list presented to the user more clean and giving them (the users) a good overview of what they are going to buy.
The goal is to show the user a list which is categorized, something like this:
VEGETABLES
Paprika
Tomatoes
VARIOUS
Toothpaste
Toilet Paper
And so on. I have like five categories saved in my database and users may choose one corresponding category once they add an item to the list below which the item will be displayed in the list.
These are my database models:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
tag = models.CharField(max_length=2)
def __str__(self):
return self.name
class Item(models.Model):
text = models.CharField(max_length=40)
count = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
complete = models.BooleanField(default=False)
def __str__(self):
return self.text
this is my views.py
def items(request):
item_list = Item.objects.order_by('id')
categories = Category.objects.all()
form = ItemForm()
context = {'item_list' : item_list, 'form' : form, 'categories' : categories}
return render(request, 'buyit/index.html', context)
and this is my index.html (very basic, stripped off all the css and html stuff):
{% for category in categories %}
<h4>{{ category.name }}</h4>
{% for item in category.item_set.all() %}
{{ item.text }}
{% endfor %}
{% endfor %}
I got this functions from the Jinja2 template from a code snippet and it might be, that I didn't understand it correctly.
However, the debugger tells me:
TemplateSyntaxError at /
Could not parse the remainder: '()' from 'category.item_set.all()'
Any hints on what I am doing wrong?
Simply displaying the categories worked fine but after adding
{% for item in category.item_set.all() %}
{{ item.text }}
{% endfor %}
things crashed.
Any help is highly appreciated!
Thanks in advance!
You can't use () in django templates. Just remove them to call the function / method.
From https://docs.djangoproject.com/en/3.1/ref/templates/language/#variables
Behind the scenes
Technically, when the template system encounters a dot, it tries the following lookups, in this order:
Dictionary lookup
Attribute or method lookup
Numeric index lookup
If the resulting value is callable, it is called with no arguments. The result of the call becomes the template value.
try this:
views.py:
def items(request):
commoditys = {category: Item.objects.filter(category=category) for category in Category.objects.all()}
form = ItemForm()
context = {'commoditys' : commoditys, 'form' : form}
return render(request, 'buyit/index.html', context)
index.html:
{% for category, commoditys in commoditys.items %}
<h3>{{ category.name }}</h3>
{% for commodity in commoditys %}
{{ commodity.text }}
{% endfor %}
{% endfor %}
Change the Category variable to a dictionary, where the Key of each item is the Category object, and its corresponding value is the item Queryset it belongs to
I am working on a studentresult website in Python and Django. Now I want to ask to the database to give me the names of the groups that are in the database. Using the standard db.sqlite3 database from django. In the Dropdown menu I get three white bars because I have three groups now. When I the Class DisplayGroups to id = Models.IntegerField(id, flat=True) change return.self.group_name to return self.id then the dropdownlist shows me the ID that the group has. But how can I show the name of the group. Tried a lot:
Changed to group in the model
Changed to groupname in the model
Changed a few of the commands in the views.py
Made a new database item Groepen and changed query to that.
views.py
from django.shortcuts import render, redirect
from .models import DisplayGroups, DisplayUsername
from django.contrib.auth.models import User, Group
def index(request):
response = redirect('/login')
return response
def home(response):
return render(response, "home/home.html")
def bekijk(request):
DisplayGroup = Group.objects.all()
print(DisplayGroup)
DisplayNames = User.objects.all()
print(DisplayNames)
return render(request, "home/bekijk.html", {"DisplayGroups": DisplayGroup,"DisplayUsername":DisplayNames})
models.py
from django.db import models
# Create your models here.
class DisplayGroups(models.Model):
group_name = models.CharField(max_length=200)
def __str__(self):
return self.group_name
class DisplayUsername(models.Model):
username = models.CharField(max_length=100)
def __str__(self):
return self.username
The html page
{% extends 'home/base.html' %}
{% block title %}Cijfers studenten{% endblock %}
{% block javascript %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function()
{
var $productvar=$("#groupdd1");
$itemvar=$("#userdd1");
$options=$itemvar.find('option');
$productvar.on('change', function()
{
$itemvar.html($options.filter('[value="'+this.value+'"]'))
}).trigger('change');
});
</script>
{% endblock %}
{% block content %}
<h1>Studentresultaten</h1>
<select id="groupdd1">
<option disabled="true" selected>-- Select Fruit --</option>
{% for result in DisplayGroups %}
<option>{{result.group_name}}</option>
{% endfor %}
</select>
<select id="userdd1">
<option disabled="true" selected>-- Select Fruit --</option>
{% for result in DisplayUsername %}
<option>{{result.username}}</option>
{% endfor %}
</select>
{% endblock %}
The piece of jquery is for later, because I want to make a dependant dropdown menu. Hope you guys can help me. Thanks in advance!
#WilliamVanOnsem is right the model from where you are filtering is Group which do not have group_name as a field. Here's what you can do.
In views.py
DisplayGroup = DisplayGroups.objects.all()
DisplayNames = DisplayName.objects.all()
Now in HTML template you can access group_name and result.username. The User model has username field so result.username did not show an empty text
Sorry the title isn't very descriptive. The context: I have an event full of participants. When the event is over I want to leave feedback for all of the other participants.
models.py
class Feedback(models.Model):
action = models.ForeignKey(Action)
feedback_by = models.ForeignKey(UserProfile, related_name='feedback_by')
feedback_for = models.ForeignKey(UserProfile, related_name='feedback_for')
comment = models.CharField(max_length=200)
no_show = models.BooleanField()
created = models.DateTimeField()
modified = models.DateTimeField()
forms.py
class FeedbackFormSet(BaseModelFormSet):
def add_fields(self, form, index):
super(FeedbackFormSet, self).add_fields(form, index)
form.fields['is_checked'] = forms.BooleanField(required=False)
class FeedbackForm(forms.ModelForm):
comment = forms.CharField(label=(u"Comment"), widget=forms.Textarea())
class Meta:
model = Feedback
fields = ['comment', 'no_show']
I want to create a feedback page, where there would be one instance of the FeedbackForm for each participant. After some searching it seems that to do that I want to be using a FormSet, but I'm not finding the documentation for it very helpful and I can't seem to find any good examples.
If a formset is the way to go, could you guys help me out with some (view/formset basically) starter code? If not, can you point me to what I should be doing? Thanks.
EDIT: I've added my view and template code below.
views.py
#login_required
def new_feedback(request, action_id):
action = get_object_or_404(Action, id=action_id)
profile = UserProfile.objects.get(user_id=request.user.id)
participants = all_info_many_profiles(action.participants.filter(~Q(id=profile.id)))
fbformset = modelformset_factory(Feedback, form=FeedbackForm, formset=FeedbackFormSet)
if request.method == 'POST':
formset = fbformset(request.POST, request.FILES, queryset=action.participants.filter(~Q(id=profile.id)))
if formset.is_valid():
formset.save()
else:
print formset.errors
else:
formset = fbformset(queryset=action.participants.filter(~Q(id=profile.id)))
return render(request, 'app/new_feedback.html',
{'action': action, 'participants': participants, 'formset': formset}
new_feedback.html
{% block body_block %}
<h1>Leave Feedback</h1>
{% for participant in participants %}
<li>{{ participant.username }}</li>
{% endfor %}
<form method="post" action="">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }} <br />
{% endfor %}
<input type="submit" name="submit" value="Submit Feedback" />
</form>
{% endblock %}
What I'm trying to achieve is to associate one form to each user in the list (or queryset) of participants. What I currently have shows one more form than I want (for example, when I list each user I'll see 3 names but 4 forms example) and I don't know if or how the users/forms are related.
The idea is that the feedback_for field will get its value automatically, ie in the view I would do:
if formset.is_valid():
for form in formset:
a = form.save(commit=false)
a.feedback = participant
a.save()
On top of that, I added an extra field "is_checked" which is intended to specify whether I'm leaving feedback for that user or not. Example of full functionality:
user1 [X] is_checked
... rest of form
user2 [] is_checked
... rest of form
user3 [X] is_checked
... rest of form
Then when I hit submit it will create two new entries in the Feedback table, one for user1 and one for user3
I have a Django app that contains info on schools and states. I want my template to display a list of schools per state and also the name of the state based on the state parameter in the URL. So if a user goes to example.com/vermont/ they will see a list of Vermont schools and a tag that says they're on the "Vermont" page. I can get the list of schools per state to work, but I can't figure out how to simply list the state name in the h1 tag.
Here is my models.py:
from django.db import models
class School(models.Model):
school_name = models.CharField(max_length=200)
location_state = models.CharField(max_length=20)
def __unicode__(self):
return self.school_name
Here is my views.py:
from django.views.generic import ListView
class StateListView(ListView):
model = School
template_name = 'state.html'
context_object_name = 'schools_by_state'
def get_queryset(self):
state_list = self.kwargs['location_state']
return School.objects.filter(location_state=state_list)
And here's my template for state.html:
{% extends 'base.html' %}
{% block content %}
<h1>{{school.location_state }}</h1> [THIS IS THE LINE THAT DOES NOT WORK]
{% for school in schools_by_state %}
<ul>
<li>{{ school.school_name }}</li>
</ul>
{% endfor %}
{% endblock content %}
What am I missing here?
The problem is that the school variable never enters the context. You are only setting the schools_by_state to the context.
To add some extra context you need to override the get_context_data method. This way you can add the location_state from the url parameter:
def get_context_data(self, **kwargs):
context = super(StateListView, self).get_context_data(**kwargs)
context.update({'state': self.kwargs['location_state']})
return context
Then you can use the {{ state }} instead of {{ school.location_state }} in your template.