Reputation: 15
I'm using Django v1.11.8 and Python 2.7.6
I got some question about edit form. Can someone explain me how to write correct edit form in Django? I'm working whole day and still got some problems... I saw lot of examples in Internet but i still do something wrong.
My ModelForm looks like this:
class UpdateVoteForm(ModelForm):
class Meta:
model = Vote
fields = ['question', 'ans_a', 'ans_b', 'ans_c', 'ans_d', 'ans_e', 'ans_f', 'type', 'council', 'user', 'created_date', 'group']
view function:
def update_vote_from(request, pk):
vote_inst = get_object_or_404(Vote, pk = pk)
if request.method == 'POST':
form = UpdateVoteForm(request.POST, instance=vote_inst)
if form.is_valid():
#vote_inst = form.save(commit=False)
#vote_inst.created_date = datetime.date.today()
form.save()
return HttpResponseRedirect(reverse('voting-list'))
else:
form = UpdateVoteForm()
return render(request, 'votes-form.html', {'form': form, 'vote_inst': vote_inst})
urls:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^votersList/$', views.VotersView.as_view(), name='voters-list'),
url(r'^vote/create/$', views.add_vote_from, name='vote-create'),
url(r'^vote/(?P<pk>\d+)/edit/$', views.update_vote_from, name='vote-update'),
]
and template:
{% extends "base_generic.html" %}
{% block content %}
<div class="containter">
<form action="" method="post">
{% csrf_token %}
<label for="user">Właściciel: </label>
<select id="user" name="user">
{% for user in vote_inst.user.all %}
<option value="{{ user }}"{% if vote_inst.user == user %} selected{% endif %}>{{ user }}</option>
{% endfor %}
</select>
<label for="user">Kto: </label>
<input id="user" type="text" name="user" value="{{ vote_inst.user }}">
<label for="question">Pytanie: </label>
<textarea id="question" name="question" style="height:70px" value="{{ vote_inst.question.value }}"></textarea>
<label for="ans_a">Odpowiedź A: </label>
<input id="ans_a" type="text" name="ans_a" placeholder="Wpisz odpowiedź A" value="{{ vote_inst.ans_a }}">
<label for="ans_b">Odpowiedź B: </label>
<input id="ans_b" type="text" name="ans_b" value="{{ vote_inst.ans_b }}">
<label for="ans_c">Odpowiedź C: </label>
<input id="ans_c" type="text" name="ans_c" value="{{ vote_inst.ans_c }}">
<label for="ans_d">Odpowiedź D: </label>
<input id="ans_d" type="text" name="ans_d" value="{{ vote_inst.ans_d }}">
<label for="ans_e">Odpowiedź E: </label>
<input id="ans_e" type="text" name="ans_e" value="{{ vote_inst.ans_e }}">
<label for="ans_f">Odpowiedź F: </label>
<input id="ans_f" type="text" name="ans_f" value="{{ vote_inst.ans_f }}">
<label for="type">Typ głosowania: </label>
<select id="type" name="type">
{% for x,y in vote_inst.type_choices %}
<option value="{{ x }}"{% if vote_inst.type == x %} selected{% endif %}>{{ y }}</option>
{% endfor %}
</select>
<input type="submit" value="Zatwierdź" />
</form>
</div>
{% endblock %}
Model:
class Vote(models.Model):
STATUS_INACTIVE = 0
STATUS_ACTIVE_NOW = 1
STATUS_FINISHED = 2
STATUS_DELETED = 3
TYPE_UNDECLARED = 0
TYPE_PUBLIC = 1
TYPE_NONPUBLIC = 2
NO_RESULT = 0
RESULT_A = 1
RESULT_B = 2
RESULT_C = 3
RESULT_D = 4
RESULT_E = 5
RESULT_F = 6
user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
voted_list = models.ManyToManyField(
Voter,
through='Voted',
#through_fields=('Vote', 'Voter'),
)
council = models.ForeignKey(Council, on_delete=models.CASCADE)
type_choices = (
(TYPE_PUBLIC, 'Jawne'),
(TYPE_NONPUBLIC, 'Niejawne'),
)
type = models.IntegerField(choices=type_choices, default=TYPE_PUBLIC)
status_choices = (
(STATUS_INACTIVE, 'Nieaktywne'),
(STATUS_ACTIVE_NOW, 'Aktywne'),
(STATUS_FINISHED, 'Zakończone'),
)
status = models.IntegerField(choices=status_choices, default=STATUS_INACTIVE)
question = models.TextField()
ans_a = models.TextField(null=True, blank=True)
ans_b = models.TextField(null=True, blank=True)
ans_c = models.TextField(null=True, blank=True)
ans_d = models.TextField(null=True, blank=True)
ans_e = models.TextField(null=True, blank=True)
ans_f = models.TextField(null=True, blank=True)
result_choices = (
(NO_RESULT, 'No result'),
(RESULT_A, 'A'),
(RESULT_B, 'B'),
(RESULT_C, 'C'),
(RESULT_D, 'D'),
(RESULT_E, 'E'),
(RESULT_F, 'F'),
)
result = models.IntegerField(choices=result_choices, default=NO_RESULT)
begin_date = models.DateTimeField(null=True, blank=True)
finish_date = models.DateTimeField(null=True, blank=True)
created_date = models.DateTimeField(default=timezone.now)
def get_status(self):
return self.status_choices[self.status][1]
def get_absolute_url(self):
return reverse('vote-update', args=[str(self.id)])
def __unicode__(self):
return "%s" % self.question
class User(models.Model):
STATUS_INACTIVE = 0
STATUS_ACTIVE = 1
STATUS_DELETED = 2
PRIVILIGES_UNDECLARED = 0
PRIVILIGES_ADMIN = 1
PRIVILIGES_MANAGER = 2
PRIVILIGES_REPORTER = 3
forename = models.CharField(max_length=50)
name = models.CharField(max_length=50)
login = models.CharField(max_length=30)
password = models.CharField(max_length=50)
last_login = models.DateTimeField(null=True, blank=True)
priviliges_choices = (
(PRIVILIGES_UNDECLARED ,'Undeclared'),
(PRIVILIGES_ADMIN ,'Administrator'),
(PRIVILIGES_MANAGER ,'Voting Manager'),
(PRIVILIGES_REPORTER ,'Reporter'),
)
priviligies = models.IntegerField(choices=priviliges_choices, default=PRIVILIGES_UNDECLARED)
status_choices = (
(STATUS_INACTIVE ,'Inactive'),
(STATUS_ACTIVE ,'Active'),
(STATUS_DELETED ,'Deleted'),
)
status = models.IntegerField(choices=status_choices, default=STATUS_INACTIVE)
def get_absolute_url(self):
return reverse('user-detail', args=[str(self.id)])
def __unicode__(self):
return "%s: %s %s" % (self.login, self.forename, self.name)
There is few things:
Upvotes: 0
Views: 5849
Reputation: 599490
You shouldn't be doing any of this. Most of your problems are caused by trying to output the form fields yourself, instead of letting Django do it. Remove all of that and either just use {{ form.as_p }}
, or iterate through the form fields and output each one:
{{ form.user.label_tag }}
{{ form.user }}
{{ form.user.errors }}
Upvotes: 2