我正在尝试解决以下问题:
我有一个只能看版主的网页。
此页面上显示的字段(在用户注册后):
用户名,名字+姓氏,电子邮件,状态,相关性等。
我需要使用此字段显示存储在db中的所有用户的信息的表,但是有两个字段有选项,所以我想选择主持人可以选择另一个选项,然后点击“更新”按钮后这个字段将为所选用户更新。
我可以显示“状态”和“相关性”字段的所有选项,在我从下拉列表中选择新选项后,数据库会更新。
我想显示下拉列表,应该选择存储在db中的选项。
我已经尝试了很多选项,我搜索了很多时间,并在StackOverFlow中搜索答案或正确的方向,但没有找到任何东西。
抱歉我的英文不好,并提前感谢您的帮助!
models.py :
class Profile(models.Model):
user = models.OneToOneField(User)
status = models.IntegerField(choices=((1, _("Not relevant")),
(2, _("Review")),
(3, _("Maybe relevant")),
(4, _("Relevant")),
(5, _("Leading candidate"))),
default=1)
relevance = models.IntegerField(choices=((1, _("Unread")),
(2, _("Read"))),
default=1)
forms.py :
class CViewerForm(forms.Form):
status = forms.ChoiceField(label="",
initial='',
widget=forms.Select(),
required=True)
relevance = forms.ChoiceField(widget=forms.Select(),
required=True)
views.py :
@group_required('Managers')
@render_to('reader/view.html')
def admins_view(request):
users_list = Profile.objects.select_related('user').all()
users_dict = dict()
if request.method and request.method == 'POST':
form = CViewerForm(request.POST)
if form.is_valid():
d = form.cleaned_data
# get all selected choices
status_list = request.POST.getlist('status')
relevance_list = request.POST.getlist('relevance')
# get all usernames viewed on page
users_list = request.POST.getlist('username')
# create dict from all those lists
users_dict = zip([user for user in users_list], [status for status in status_list], [rel for rel in relevance_list])
# run through dict and do bulk update
for user_dict in users_dict:
Profile.objects.filter(user__username=user_dict[0]).update(status=user_dict[1], relevance=user_dict[2])
return HttpResponseRedirect(reverse('reader:admins_view'))
else:
form = CViewerForm()
return {'users_list': users_list,
'user': request.user,
'form': form}
模板:
<form class="form-horizontal" action="" method="post" name="update-form" class="well form-inline" id="view_form">
{% csrf_token %}
{{ form.non_field_errors }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% if user.is_staff %}
<div>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>{% trans 'Username' %} </th>
<th>{% trans 'E-mail' %} </th>
<th>{% trans 'Status' %} </th>
<th>{% trans 'Relevance' %} </th>
</tr>
</thead>
<tbody>
{% for user in users_list %}
<tr>
<td><input type="text" READONLY name="username" value="{{ user.user.username }}"></td>
<td>{{ user.user.first_name }}</td>
<td>{{ user.user.last_name }}</td>
<td>{{ user.user.email }}</td>
<td>{{ user.get_status_display }}</td>
<td>{{ user.get_relevance_display }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<br>
{% endif %}
<div class="form-actions">
<input type="hidden" name="_cmd_personal">
<input type="submit" class="btn btn-info" value="{% trans 'Update' %}" name="update" class="default">
</div>
</form>
以下是解决方案:
forms.py(正如@Liarez所写)。
模板:
<form class="form-horizontal" action="" method="post" name="update-form" class="well form-inline" id="view_form">
{% csrf_token %}
{% if user.is_staff %}
{% if users_list %}
<div>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>{% trans 'Username' %} </th>
<th>{% trans 'First name' %} </th>
<th>{% trans 'Last name' %} </th>
<th>{% trans 'E-mail' %} </th>
<th>{% trans 'CV Status' %} </th>
<th>{% trans 'CV Relevance' %} </th>
</tr>
</thead>
<tbody>
{% for user in users_list %}
<tr>
<td><input type="text" READONLY name="username" value="{{ user.user.username }}"></td>
<td>{{ user.user.first_name }}</td>
<td>{{ user.user.last_name }}</td>
<td>{{ user.user.email }}</td>
<td>
<select name="cv_status">
{% for key, status in status_choices %}
{% ifequal user.get_cv_status_display status %}
<option value="{{ user.cv_status }}" selected>{{ user.get_cv_status_display }}</option>
{% else %}
<option value="{{ key }}">{{ status }}</option>
{% endifequal %}
{% endfor %}
</select>
</td>
<td>
<select name="cv_signal">
{% for key, signal in signal_choices %}
{% ifequal user.get_cv_signal_display signal %}
<option value="{{ user.cv_signal }}" selected>{{ user.get_cv_signal_display }}</option>
{% else %}
<option value="{{ key }}">{{ signal }}</option>
{% endifequal %}
{% endfor %}
</select>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<br>
{% endif %}
<div class="form-actions">
<input type="submit" class="btn btn-info" value="{% trans 'Update' %}" name="update" class="default">
</div>
答案 0 :(得分:43)
首先我推荐你@ ChrisHuang-Leaver建议定义一个新文件,其中包含你需要的所有选项,例如choices.py
:
STATUS_CHOICES = (
(1, _("Not relevant")),
(2, _("Review")),
(3, _("Maybe relevant")),
(4, _("Relevant")),
(5, _("Leading candidate"))
)
RELEVANCE_CHOICES = (
(1, _("Unread")),
(2, _("Read"))
)
现在您需要在模型上导入它们,因此代码很容易理解( models.py ):
from myApp.choices import *
class Profile(models.Model):
user = models.OneToOneField(User)
status = models.IntegerField(choices=STATUS_CHOICES, default=1)
relevance = models.IntegerField(choices=RELEVANCE_CHOICES, default=1)
你必须在 forms.py 中导入选项:
forms.py:
from myApp.choices import *
class CViewerForm(forms.Form):
status = forms.ChoiceField(choices = STATUS_CHOICES, label="", initial='', widget=forms.Select(), required=True)
relevance = forms.ChoiceField(choices = RELEVANCE_CHOICES, required=True)
无论如何,您的模板存在问题,因为您没有使用任何{{form.field}}
,因此您生成了一个表,但没有输入只有hidden_fields。
当用户是员工时,您应该生成与您可以管理的用户一样多的输入字段。我认为django形式不是最适合您情况的解决方案。
我认为使用html表单会更好,因此您可以使用boucle生成尽可能多的输入:{% for user in users_list %}
并生成带有与用户相关的ID的输入,并且您可以管理所有他们在视野中。
答案 1 :(得分:1)
Django 3中的新方法
您可以使用 Field.choices 枚举在django3中键入新更新,如下所示:
from django.db import models
class Status(models.TextChoices):
UNPUBLISHED = 'UN', 'Unpublished'
PUBLISHED = 'PB', 'Published'
class Book(models.Model):
status = models.CharField(
max_length=2,
choices=Status.choices,
default=Status.UNPUBLISHED,
)
答案 2 :(得分:0)
如果您的选择不是预先确定的,或是来自其他来源,则可以在视图中生成它们并将其传递给表单。
示例:
views.py:
def my_view(request, interview_pk):
interview = Interview.objects.get(pk=interview_pk)
all_rounds = interview.round_set.order_by('created_at')
all_round_names = [rnd.name for rnd in all_rounds]
form = forms.AddRatingForRound(all_round_names)
return render(request, 'add_rating.html', {'form': form, 'interview': interview, 'rounds': all_rounds})
forms.py
class AddRatingForRound(forms.ModelForm):
def __init__(self, round_list, *args, **kwargs):
super(AddRatingForRound, self).__init__(*args, **kwargs)
self.fields['name'] = forms.ChoiceField(choices=tuple([(name, name) for name in round_list]))
class Meta:
model = models.RatingSheet
fields = ('name', )
模板:
<form method="post">
{% csrf_token %}
{% if interview %}
{{ interview }}
{% endif %}
{% if rounds %}
<hr>
{{ form.as_p }}
<input type="submit" value="Submit" />
{% else %}
<h3>No rounds found</h3>
{% endif %}
</form>
答案 3 :(得分:0)
在Django模型中提供选择的更好方法:
from django.db import models
class Student(models.Model):
FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
GRADUATE = 'GR'
YEAR_IN_SCHOOL_CHOICES = [
(FRESHMAN, 'Freshman'),
(SOPHOMORE, 'Sophomore'),
(JUNIOR, 'Junior'),
(SENIOR, 'Senior'),
(GRADUATE, 'Graduate'),
]
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)