0

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

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

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)

在我的表单中,我正在编辑一个从实体派生的模型:

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 新手,所以我的一些尝试可能很天真。我的解决方案是制作两个从 ModelForm 继承的用于 Point and Place 的表单和一个用于标记的自定义表单。在标签形式中,我想让用户从数据库中选择现有标签或键入用“;”分隔的新标签 在文本输入中。所以我创建了这三种形式:

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. 为什么在提交带有空白 newTags 且未选择 tagsAll 字段的表单后,我的 tagsAll 字段出现错误(它出现在表单上 tagsAll 字段上方):

“null”不是主键的有效值

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

4

0 回答 0