Django表单:显示错误“null”的ModelMultipleChoiceField不是主键的有效值

时间:2012-04-26 01:23:54

标签: django django-models django-forms

如下所述,我将尝试使用更多代码示例更准确地解释我的问题

在我的应用程序中,我使用模型继承,其中基本模型类是:

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;

}

在这里,我不仅要问一个主题问题:

  1. 这样做是更好的解决方案吗? (好吧,我可以创建一个自定义表单但是我放松了一些自动化部件......)

  2. 为什么在提交带有空白newTag的表单并且没有对tagsAll字段进行选择后,我对tagsAll字段有错误(它出现在表单上,​​在tagsAll字段上方):

  3. “null”不是主键的有效值

    我在使用AJAX时在表单上显示错误也有问题...:/我找到了解决方案,我必须在模板上手动迭代它们(http://infinite-sushi.com/2011 / 06 / using-ajax-with-django /)..对于任何其他解决方案,我将不胜感激:))

0 个答案:

没有答案