такие самореферентные структуры являются точной причиной того, почему std::pin
был введен. Вы можете проверить этот RFC и этот пример из документации.
Я подозреваю что __unicode__
метод для экземпляра модели Profile, или repr
этого установлен возвратить значение кроме self.id
. Например, я просто настроил это:
# models.py
class Profile(models.Model):
name = models.CharField('profile name', max_length=10)
def __unicode__(self):
return u'%d' % self.id
class Plan(models.Model):
name = models.CharField('plan name', max_length=10)
profile = models.ForeignKey(Profile, related_name='profiles')
def __unicode__(self):
return self.name
# forms.py
class PlanForm(forms.ModelForm):
profile = forms.ModelChoiceField(queryset=Profile.objects.all(),
widget=forms.HiddenInput())
class Meta:
model = Plan
# views.py
def add_plan(request):
if request.method == 'POST':
return HttpResponse(request.POST['profile'])
profile = Profile.objects.all()[0]
form = PlanForm(initial={'profile':profile})
return render_to_response('add_plan.html',
{
'form':form,
},
context_instance=RequestContext(request))
С этим я вижу PlanForm.profile, представленный таким образом в шаблоне:
<input type="hidden" name="profile" value="1" id="id_profile" />
Хм...
Это могло бы на самом деле быть дырой в системе безопасности.
Предположим, что злонамеренный взломщик обработал POST (скажите, при помощи XmlHttpRequest от FireBug), и установите сроки профиля к некоторому дурацкому значению, как, Ваш идентификатор профиля. Вероятно, не, что Вы хотели?
Если возможно, можно хотеть получить профиль от самого объекта запроса, а не что отправляется от значений POST.
form = PlanForm(request.POST)
if form.is_valid():
plan = form.save(commit=False)
plan.owner = request.user.get_profile()
plan.save()
form.save_m2m() # if neccesary
Когда Вы присваиваете объект Профиля форме, Django stringifies это, и использует вывод в качестве значения в форме. Что Вы ожидали бы, хотя, чтобы Django использовал идентификатор объекта вместо этого.
К счастью обходное решение просто: Просто дайте значения первичного ключа формы объектов Профиля вместо этого:
form = PlanForm(initial={'profile': profile.pk})
На другом конце, когда Вы работаете со связанными формами, однако, они работают намного более разумно:
form = PlanForm(request.POST)
if form.is_valid():
print form.cleaned_data['profile'] # the appropriate Profile object
Обычно нет никакой потребности поместить связанный объект в поле формы. Существует лучший путь, и это указывает родительский идентификатор в URL формы.
Давайте предположим, что необходимо представить форму для нового Плана, возражают и затем создают тот, когда форма является bubmitted. Вот то, как Ваш urlconf был бы похож:
(r"/profile/(?P<profile_id>\d+)/plan/new", view.new_plan), # uses profile_id to define proper form action
(r"/profile/(?P<profile_id>\d+)/plan/create", view.create_plan) # uses profile_id as a Plan field
И если Вы изменяете существующий объект, все, в чем Вы нуждаетесь, plan_id, можно вывести любую связанную запись из него.