如下所述,我将尝试使用更多代码示例更准确地解释我的问题
在我的应用程序中,我使用模型继承,其中基本模型类是:
class Entity(models.Model):
VISIBILITY_LEVELS = (
('0', 'Private'),
('1', 'Closedy'),
('2', 'Public'),
)
entityType = models.CharField(max_length=50)
userCreatedBy = models.ForeignKey(User, related_name='user_createdby', editable=False)
dateCreated = models.DateField(editable=False)
lastModified = models.DateField()
lastModifiedBy = models.ForeignKey(User, related_name='user_lastModifiedBy')
tags = models.ManyToManyField('Tag', blank=True, null=True)
visibilityLevel = models.CharField(max_length=1, choices=VISIBILITY_LEVELS, default=False)
在我的表单中,我正在编辑一个派生自Entity的模型:
class Place(Entity):
name = models.CharField(max_length=155)
description = models.TextField()
location = models.ForeignKey(Point)
点和标签模型是:
class Point(models.Model):
lat = models.FloatField() #coordinates
lng = models.FloatField()
hgt = models.FloatField(default=0.0)
class Tag(models.Model):
tagName = models.CharField(max_length=250) #tag name
usedAmount = models.IntegerField(default = 1) #how many entities has this tag
所有型号都有django自动生成的主键。在我的网站中,我使用AJAX来处理表单(目前,没有AJAX验证,但它将是;) 我的第一个问题是:创建表单添加新Place对象的最简单方法是什么?最棘手的部分是标签添加,因为我需要启用两者 - 添加新标签和选择现有标签。我是Django的新手,所以我的一些尝试可能是天真的。我的解决方案是使两个Form继承自ModelForm for Point and Place和一个自定义Form for Tag。在标签表单中,我想让用户从DB中选择现有标签或键入以';'分隔的新标签在textinput中。所以我创建了这三种形式:
class PlaceAddForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PlaceAddForm, self).__init__(*args, **kwargs)
self.fields['name'].label = "Name"
self.fields['description'].label = "Desc"
self.fields['visibilityLevel'].label = "Visibility"
class Meta:
model = Place
fields = ('name', 'description',
'visibilityLevel' )
#--
class PointForm(forms.ModelForm):
class Meta:
model = Point
#---
class TagAppendForm(forms.Form):
newTags = forms.CharField(
widget=forms.TextInput(),
required = False,
)
tagsAll = forms.ModelMultipleChoiceField(
label="Choose:",
queryset=Tag.objects.all(),
required = False
)
def clean_newTags(self):
if len(self.cleaned_data['newTags']) == 0:
return []
tags = self.cleaned_data['newTags'].split(';')
for t in tags:
if len(t) == 0:
raise forms.ValidationError('Tag must be minum 3 characters long')
return tags
然后在我的模板中我有:
<form id="save-form" method="post" action="/user/places/addedit/">
{{ pointForm.as_p }}
{{ placeForm.as_p }}
{{ tagForm.as_p }}
<input type="submit" value="save" />
</form>
观点是:
def place_save_view(request):
ajax = request.GET.has_key('ajax')
if request.method == 'POST':
placeForm = PlaceAddForm(request.POST)
pointForm = PointForm(request.POST)
tagForm = TagAppendForm(request.POST)
if placeForm.is_valid() and tagForm.is_valid() and pointForm.is_valid():
place = _place_save(request, placeForm, pointForm, tagForm)
variables = RequestContext(request, {'places' : place })
return HttpResponseRedirect('/user/places/', variables)
#else:
# if ajax:
elif request.GET.has_key('entity_ptr_id'):
place = Place.objects.get(id==request.GET['entity_ptr_id'])
placeForm = PlaceAddForm(request.GET,instance=place)
point = place.location
pointForm = PointForm(request.GET,instance=point)
tagForm = TagAppendForm(initial={'tagsAll': place.tags.values_list('id', flat=True)})
else:
placeForm = PlaceAddForm()
pointForm = PointForm()
tagForm = TagAppendForm()
variables = RequestContext(request, {'placeForm': placeForm, 'pointForm': pointForm, 'tagForm': tagForm })
if ajax:
return render_to_response('places/place_save.html', variables)
else:
return render_to_response('places/add-edit-place.html', variables)
最后是AJAX:
function placeAdd() {
var div = $(document).find("#leftcontent");
div.load("/user/places/addedit/?ajax", null, function() {
$("#save-form").submit(placeSave);
});
return false;
}
function placeSave()
{
var item = $(this).parent();
var data = {
lng: item.find("#id_lng").val(),
lat: item.find("#id_lat").val(),
hgt: item.find("#id_hgt").val(),
name: item.find("#id_name").val(),
description: item.find("#id_description").val(),
pType: item.find("#id_pType").val(),
visibilityLevel: item.find("#id_visibilityLevel").val(),
newTags: item.find("#id_newTags").val(),
tagsAll: item.find("#id_tagsAll").val()
};
$.post("/user/places/addedit/?ajax", data, function(result){
if(result != "failure")
{
//todo....
}
else {
alert("Failure!");
}
});
return false;
}
在这里,我不仅要问一个主题问题:
这样做是更好的解决方案吗? (好吧,我可以创建一个自定义表单但是我放松了一些自动化部件......)
为什么在提交带有空白newTag的表单并且没有对tagsAll字段进行选择后,我对tagsAll字段有错误(它出现在表单上,在tagsAll字段上方):
“null”不是主键的有效值
我在使用AJAX时在表单上显示错误也有问题...:/我找到了解决方案,我必须在模板上手动迭代它们(http://infinite-sushi.com/2011 / 06 / using-ajax-with-django /)..对于任何其他解决方案,我将不胜感激:))