Форум сайта python.su
Столкнулся с такой задачей.
Необходимо сделать валидацию формы и выполнить запись в модель на основании данных введенных в HTML форме.
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from RandomQuote.upload.forms import UploadFileForm
from RandomQuote.settings import MEDIA_ROOT
def handle_uploaded_file(f):
destination = open(MEDIA_ROOT+'/images/'+f.name, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
def startUpload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['firstfile'])
form.save()
return HttpResponseRedirect('/')
from django import forms
class UploadFileForm(forms.Form):
author = forms.CharField(required=True)
title = forms.CharField(required=True)
describe = forms.Textarea()
tags = forms.SelectMultiple()
firstfile = forms.ImageField()
def save(self):
author = self.cleaned_data["author"]
title = self.cleaned_data["title"]
describe = self.cleaned_data["describe"]
tags = self.cleaned_data["tags"]
from RandomQuote.quotes.models import Tag, Image
Image(image_author=author,
image_title=title,
image_description=describe,
image_tags=tags
).save()
<form enctype="multipart/form-data" action="upload/" method="post">
{% csrf_token %}
<TABLE cellpadding="0" cellspacing="0" border="0">
<TR><TD><label for="id_author">Автор:</label></TD><TD><input type="text" size=20 name="author" id="id_author" value="{{ user.username }}" /></TD></TR>
<TR><TD><label for="id_title">Название:</label></TD><TD><input type="text" size=20 name="title" id="id_title" /></TD></TR>
<TR><TD><label for="id_describe">Описание:</label></TD><TD><textarea rows="10" cols="20" name="describe" id="id_describe"></textarea> </TD></TR>
<TR><TD>Дата: </TD><TD>{% now "jS F Y H:i" %}</TD></TR>
<TR><TD><label for="id_tags">Выберите теги:</label></TD><TD>
<select multiple="multiple" name="tags" id="id_tags">
{% if tags %}
{% for tag in tags.all %}
<option>{{ tag }}</option>
{% endfor %}
{% endif %}
</select>
</TD></TR>
<TR><TD><label for="id_firstfile">Файл:</label></TD><TD><input type="file" size=20 name="firstfile"
id="id_firstfile" /></TD></TR>
<TR><TD colspan="2" align="right"> <input type="submit" value="Загрузить!" /></TD></TR>
</TABLE>
</form>
from django.db import models
from django.contrib.auth.models import User
class Tag(models.Model):
tag_name = models.CharField(max_length=30)
def __unicode__(self):
return self.tag_name
class Image(models.Model):
image_author = models.ForeignKey(User)
image_title = models.CharField(max_length=30)
image_description = models.TextField(blank=True)
image_pubdate = models.DateTimeField(auto_now_add=True)
image_source = models.ImageField(upload_to='images/')
image_tags = models.ManyToManyField(Tag,blank=True)
def __unicode__(self):
return '%s (%s)' % (self.image_title, self.image_author)
class Comment(models.Model):
comment_author = models.ForeignKey(User)
comment_image = models.ForeignKey(Image)
comment_title = models.CharField(max_length=50)
comment_pubdate = models.DateTimeField(auto_now_add=True)
comment_text = models.TextField()
def __unicode__(self):
return '%s (%s)' % (self.comment_title, self.comment_author)
Отредактировано (Июнь 17, 2011 20:51:51)
Офлайн
forms.Textarea - это не поле формы, это виджет.
https://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Textarea
describe = forms.CharField(widget=forms.Textarea)
KotakotaSelectMultiple - это тоже виджет.
Второй вопрос такой…
Отредактировано (Июнь 18, 2011 13:42:21)
Офлайн
pillСпасибо.
forms.Textarea - это не поле формы, это виджет.
https://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Textareadescribe = forms.CharField(widget=forms.Textarea)KotakotaSelectMultiple - это тоже виджет.
Второй вопрос такой…
Думаю ModelMultipleChoiceField - то что вам нужно
Зы: Зачем в темплейте руками форму описывать, чем form.as_table не угодил то?
from django import forms
class UploadFileForm(forms.Form):
author = forms.CharField()
title = forms.CharField()
describe = forms.CharField()
tags = forms.ModelMultipleChoiceField(queryset=Value.objects.none())
firstfile = forms.ImageField()
def save(self):
author = self.cleaned_data["author"]
title = self.cleaned_data["title"]
describe = self.cleaned_data["describe"]
tags = self.cleaned_data["tags"]
from RandomQuote.quotes.models import Tag, Image
Image(image_author=author,
image_title=title,
image_description=describe,
image_tags=tags
).save()
Офлайн
Value.objects.none() что вы под этим подразумеваете?
Модели Value у вас нет, а objects.none() - возвращает пустой queryset - Соответственно выбирать было бы не из чего…
если все теги нужны:
tags = forms.ModelMultipleChoiceField(Tag.objects.all())
Отредактировано (Июнь 20, 2011 09:25:15)
Офлайн
pillВ аргумент ModelMultipleChoiceField() мы передаем кверисет из чего мы должны выбирать?
Value.objects.none() что вы под этим подразумеваете?
Модели Value у вас нет, а objects.none() - возвращает пустой queryset - Соответственно выбирать было бы не из чего…
если все теги нужны:tags = forms.ModelMultipleChoiceField(Tag.objects.all())
ValueError at /upload/
The view upload.views.startUpload didn't return an HttpResponse object.
Request Method: POST
Request URL: http://localhost/upload/
Django Version: 1.3
Exception Type: ValueError
Exception Value:
The view upload.views.startUpload didn't return an HttpResponse object.
Exception Location: C:\Python27\lib\site-packages\django\core\handlers\base.py in get_response, line 129
Python Executable: C:\Python27\python.exe
Python Version: 2.7.1
Python Path:
['C:\\RandomQuote',
'C:\\WINDOWS\\system32\\python27.zip',
'C:\\Python27\\DLLs',
'C:\\Python27\\lib',
'C:\\Python27\\lib\\plat-win',
'C:\\Python27\\lib\\lib-tk',
'C:\\Python27',
'C:\\Python27\\lib\\site-packages',
'C:\\Python27\\lib\\site-packages\\PIL']
Server time: Mon, 20 Jun 2011 13:46:31 +0700
Traceback Switch to copy-and-paste view
C:\Python27\lib\site-packages\django\core\handlers\base.py in get_response
raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
...
▶ Local vars
Офлайн
KotakotaДа.
В аргумент ModelMultipleChoiceField() мы передаем кверисет из чего мы должны выбирать?
KotakotaЗначит данные не походят валидацию, вы ведь возвращаете HttpResponse только если все ок.if form.is_valid(): handle_uploaded_file(request.FILES['firstfile']) form.save() return HttpResponseRedirect('/')
<select multiple="multiple" name="tags" id="id_tags">
{% if tags %}
{% for tag in tags.all %}
<option>{{ tag }}</option>
{% endfor %}
{% endif %}
<p class="required"><label for="id_operators">Operators:</label> <select multiple="multiple" name="operators" id="id_operators">
<option value="3">Левый</option>
<option value="2">ВИнни Пух</option>
...
#тобишь что-то вроде
{% if tags %}
{% for tag in tags.all %}
<option value="{{tag.id}}">{{ tag }}</option>
{% endfor %}
{% endif %}
Отредактировано (Июнь 20, 2011 10:40:11)
Офлайн
Переделал
{% if tags %}
{% for tag in tags.all %}
<option>{{ tag }}</option>
{% endfor %}
{% endif %}
{% if tags %}
{% for tag in tags.all %}
<option value="{{tag.id}}">{{ tag }}</option>
{% endfor %}
{% endif %}[
ValueError at /upload/
Cannot assign "u'root'": "Image.image_author" must be a "User" instance.
Request Method: POST
Request URL: http://localhost/upload/
Django Version: 1.3
Exception Type: ValueError
Exception Value:
Cannot assign "u'root'": "Image.image_author" must be a "User" instance.
Exception Location: C:\Python27\lib\site-packages\django\db\models\fields\related.py in __set__, line 331
Python Executable: C:\Python27\python.exe
Python Version: 2.7.1
Python Path:
['C:\\RandomQuote',
'C:\\WINDOWS\\system32\\python27.zip',
'C:\\Python27\\DLLs',
'C:\\Python27\\lib',
'C:\\Python27\\lib\\plat-win',
'C:\\Python27\\lib\\lib-tk',
'C:\\Python27',
'C:\\Python27\\lib\\site-packages',
'C:\\Python27\\lib\\site-packages\\PIL']
Server time: Mon, 20 Jun 2011 15:09:40 +0700
Traceback Switch to copy-and-paste view
C:\Python27\lib\site-packages\django\core\handlers\base.py in get_response
response = callback(request, *callback_args, **callback_kwargs)
...
▶ Local vars
C:\RandomQuote\upload\views.py in startUpload
form.save()
...
▶ Local vars
C:\RandomQuote\..\RandomQuote\upload\forms.py in save
image_tags=tags
...
▶ Local vars
C:\Python27\lib\site-packages\django\db\models\base.py in __init__
setattr(self, field.name, rel_obj)
...
▶ Local vars
C:\Python27\lib\site-packages\django\db\models\fields\related.py in __set__
self.field.name, self.field.rel.to._meta.object_name))
...
▶ Local vars
def save(self):
author = 'root'
#author = self.cleaned_data["author"]
title = self.cleaned_data["title"]
describe = self.cleaned_data["describe"]
tags = self.cleaned_data["tags"]
from RandomQuote.quotes.models import Image
Image(image_author=author,
image_title=title,
image_description=describe,
image_tags=tags
).save()
ValueError at /upload/
Cannot assign "'root'": "Image.image_author" must be a "User" instance.
Request Method: POST
Request URL: http://localhost/upload/
Django Version: 1.3
Exception Type: ValueError
Exception Value:
Cannot assign "'root'": "Image.image_author" must be a "User" instance.
Exception Location: C:\Python27\lib\site-packages\django\db\models\fields\related.py in __set__, line 331
Python Executable: C:\Python27\python.exe
Python Version: 2.7.1
Python Path:
['C:\\RandomQuote',
'C:\\WINDOWS\\system32\\python27.zip',
'C:\\Python27\\DLLs',
'C:\\Python27\\lib',
'C:\\Python27\\lib\\plat-win',
'C:\\Python27\\lib\\lib-tk',
'C:\\Python27',
'C:\\Python27\\lib\\site-packages',
'C:\\Python27\\lib\\site-packages\\PIL']
Server time: Mon, 20 Jun 2011 15:14:39 +0700
Офлайн
Вам же человеческим языком пишет:
KotakotaХочу получить инстанс юзера, а вы ему имя юзера, тобишь, строку передаете.
assign “'root'”: “Image.image_author” must be a “User” instance.
</TD><TD><input type="text" size=20 name="author" id="id_author" value="{{ user.id}}" /></TD></TR>
def save(self):
try:
author = User.objects.get(id=int(self.cleaned_data["author"]))
except User.DoesNotExist:
return
title = self.cleaned_data["title"]
или если темплейт не менять:
...
def save(self):
try:
author = User.objects.get(username=self.cleaned_data["author"])
except User.DoesNotExist:
return
title = self.cleaned_data["title"]
...
Отредактировано (Июнь 20, 2011 11:43:11)
Офлайн
Большое спасибо!
Я обязательно буду использовать as_table, просто хочу понять как это обрабатывается html форма сделанная вручную.
При добавлении появляется следующая ошибка:
ypeError at /upload/
'image_tags' is an invalid keyword argument for this function
Request Method: POST
Request URL: http://localhost/upload/
Django Version: 1.3
Exception Type: TypeError
Exception Value:
'image_tags' is an invalid keyword argument for this function
Exception Location: C:\Python27\lib\site-packages\django\db\models\base.py in __init__, line 364
Python Executable: C:\Python27\python.exe
Python Version: 2.7.1
Python Path:
['C:\\RandomQuote',
'C:\\WINDOWS\\system32\\python27.zip',
'C:\\Python27\\DLLs',
'C:\\Python27\\lib',
'C:\\Python27\\lib\\plat-win',
'C:\\Python27\\lib\\lib-tk',
'C:\\Python27',
'C:\\Python27\\lib\\site-packages',
'C:\\Python27\\lib\\site-packages\\PIL']
Server time: Mon, 20 Jun 2011 16:37:24 +0700
from django import forms
from RandomQuote.quotes.models import Tag
from django.contrib.auth.models import User
class UploadFileForm(forms.Form):
author = forms.CharField()
title = forms.CharField()
describe = forms.CharField()
tags = forms.ModelMultipleChoiceField(Tag.objects.all())
firstfile = forms.ImageField()
def save(self):
try:
author = User.objects.get(username=self.cleaned_data["author"])
except User.DoesNotExist:
return
#author = self.cleaned_data["author"]
title = self.cleaned_data["title"]
describe = self.cleaned_data["describe"]
tags = self.cleaned_data["tags"]
from RandomQuote.quotes.models import Image
Image(image_author=author,
image_title=title,
image_description=describe,
image_tags=tags
).save()
Офлайн
KotakotaОсобенность реализации ManyToMany (Там ведь промежуточная таблица создается).
Как можно правильно присвоить теги из <select> полю image_tags?
image = Image(image_author=author,
image_title=title,
image_description=describe)
image.save()
image.image_tags = self.cleaned_data["tags"]
image.save()
Отредактировано (Июнь 20, 2011 13:21:17)
Офлайн