以下にコメントしたように、より多くのコード例を使用して問題をより正確に説明しようとします
私のアプリケーションでは、モデル継承を使用しています。基本モデル クラスは次のとおりです。
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から継承された2つのフォームとタグの1つのカスタムフォームを作成することでした。タグ形式で、ユーザーが DB から既存のタグを選択したり、「;」で区切られた新しいタグを入力できるようにしたいと考えています。テキスト入力で。だから私はそれらの3つのフォームを作成しました:
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 つのカスタム フォームを作成できますが、いくつかの自動化パーツが失われます...)
newTags が空白で、tagsAll フィールドが選択されていないフォームを送信した後、tagsAll フィールドでエラーが発生するのはなぜですか (フォームの tagsAll フィールドの上に表示されます)。
「null」は主キーの有効な値ではありません
AJAXが使用されている場合、フォームにエラーを表示することにも問題があります... :/フォームを使用してテンプレートで手動で反復処理する必要があるという解決策を見つけました(http://infinite-sushi.com/2011/06/ using-ajax-with-django/)..他のソリューションについては、感謝します:)