Django:访问新linline对象中的父对象
我在互联网上搜索了很长一段时间,没有找到任何解决这个问题的方法 我想做的是 我有以下型号:Django:访问新linline对象中的父对象,django,django-forms,django-admin,Django,Django Forms,Django Admin,我在互联网上搜索了很长一段时间,没有找到任何解决这个问题的方法 我想做的是 我有以下型号: class TrackingEventType(models.Model): required_previous_event = models.ForeignKey(TrackingEventType) class TrackingEvent(models.Model): tracking = models.ForeignKey(Tracking) class Tracking(mod
class TrackingEventType(models.Model):
required_previous_event = models.ForeignKey(TrackingEventType)
class TrackingEvent(models.Model):
tracking = models.ForeignKey(Tracking)
class Tracking(models.Model):
last_event = models.ForeignKey(TrackingEvent)
现在主要模型是跟踪,因此我的跟踪管理员如下所示:
class TrackingEventInline(admin.TabularInline):
model = TrackingEvent
extra = 0
class TrackingAdmin(admin.ModelAdmin):
inlines = [TrackingEventInline]
这就是当前设置的内容
现在我的任务是:
在TrackingAdmin中,当我添加新的TrackingEvent内联线时,我想将TrackingEventType的选项限制为仅允许跟踪跟踪的最后一个TrackingEvent的选项。(Tracking.last\u event==TrackingEventType.required\u previous\u event)
为此,我需要能够访问InlineTrackingEvent上的相关跟踪,访问最后一个事件并相应地过滤TrackingEventType的选项
所以我发现了这个:,但是当我相应地设置TrackingEventInline时:
class MyFormSet(forms.BaseInlineFormSet):
def _construct_form(self, i, **kwargs):
kwargs['parent_object'] = self.instance
print self.instance
return super(MyFormSet, self)._construct_form(i, **kwargs)
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
print kwargs
self.parent_object = kwargs.pop('parent_object')
super(MyForm, self).__init__(*args, **kwargs)
class TrackingEventInline(admin.TabularInline):
form = MyForm
formset = MyFormSet
model = TrackingEvent
extra = 0
我在/admin/../tracking/2/change/'parent\u object'处收到一个键错误,来自self.parent\u object=kwargs.pop('parent\u object')
有人知道如何解决这个问题吗?我是否以错误的方式处理问题?我想这在前端的自定义表单中会很容易,但我真的想使用管理员,因为整个应用程序都是从管理员那里构建的,而仅仅因为这个问题,构建自定义管理员界面需要做大量的工作:)好的,因此,在StackOverflow上发帖总是有助于解决问题。我能想出一个适合我的解决方案
它包括在外部函数中定义我自己的表单,以及为TrackingEvent定义两个InlineAdmin对象(一个用于更新/编辑,一个仅用于插入)
代码如下:
def create_trackingevent_form(tracking):
"""
"""
class TrackingEventForm(forms.ModelForm):
"""
Form for Tracking Event Inline
"""
def clean(self):
"""
May not be needed anymore, since event type choices are limited when creating new event.
"""
next_eventtype = self.cleaned_data['event_type']
tracking = self.cleaned_data['tracking']
# get last event, this also ensures last_event gets updated everytime the change form for TrackingEvent is loaded
last_eventtype = tracking.set_last_event()
if last_eventtype:
last_eventtype = last_eventtype.event_type
pk = self.instance.pk
insert = pk == None
# check if the event is updated or newly created
if insert:
if next_eventtype.required_previous_event == last_eventtype:
pass
else:
raise forms.ValidationError('"{}" requires "{}" as last event, "{}" found. Possible next events: {}'.format(
next_eventtype,
next_eventtype.required_previous_event,
last_eventtype,
'"%s" ' % ', '.join(map(str, [x.name for x in tracking.next_tracking_eventtype_options()]))
)
)
else:
pass
return self.cleaned_data
def __init__(self, *args, **kwargs):
# You can use the outer function's 'tracking' here
self.parent_object = tracking
super(TrackingEventForm, self).__init__(*args, **kwargs)
self.fields['event_type'].queryset = tracking.next_tracking_eventtype_options()
#self.fields['event_type'].limit_choices_to = tracking.next_tracking_eventtype_options()
return TrackingEventForm
class TrackingEventInline(admin.TabularInline):
#form = MyForm
#formset = MyFormSet
model = TrackingEvent
extra = 0
#readonly_fields = ['datetime', 'event_type', 'note']
def has_add_permission(self, request):
return False
class AddTrackingEventInline(admin.TabularInline):
model = TrackingEvent
extra = 0
def has_change_permission(self, request, obj=None):
return False
def queryset(self, request):
return super(AddTrackingEventInline, self).queryset(request).none()
def get_formset(self, request, obj=None, **kwargs):
if obj:
self.form = create_trackingevent_form(obj)
return super(AddTrackingEventInline, self).get_formset(request, obj, **kwargs)
我希望这能帮助其他有同样问题的人。。堆栈溢出线程帮助我实现了以下目标:
如果您有任何问题,请不要犹豫提问,因此在StackOverflow上发布总是有助于解决问题。我能想出一个适合我的解决方案
它包括在外部函数中定义我自己的表单,以及为TrackingEvent定义两个InlineAdmin对象(一个用于更新/编辑,一个仅用于插入)
代码如下:
def create_trackingevent_form(tracking):
"""
"""
class TrackingEventForm(forms.ModelForm):
"""
Form for Tracking Event Inline
"""
def clean(self):
"""
May not be needed anymore, since event type choices are limited when creating new event.
"""
next_eventtype = self.cleaned_data['event_type']
tracking = self.cleaned_data['tracking']
# get last event, this also ensures last_event gets updated everytime the change form for TrackingEvent is loaded
last_eventtype = tracking.set_last_event()
if last_eventtype:
last_eventtype = last_eventtype.event_type
pk = self.instance.pk
insert = pk == None
# check if the event is updated or newly created
if insert:
if next_eventtype.required_previous_event == last_eventtype:
pass
else:
raise forms.ValidationError('"{}" requires "{}" as last event, "{}" found. Possible next events: {}'.format(
next_eventtype,
next_eventtype.required_previous_event,
last_eventtype,
'"%s" ' % ', '.join(map(str, [x.name for x in tracking.next_tracking_eventtype_options()]))
)
)
else:
pass
return self.cleaned_data
def __init__(self, *args, **kwargs):
# You can use the outer function's 'tracking' here
self.parent_object = tracking
super(TrackingEventForm, self).__init__(*args, **kwargs)
self.fields['event_type'].queryset = tracking.next_tracking_eventtype_options()
#self.fields['event_type'].limit_choices_to = tracking.next_tracking_eventtype_options()
return TrackingEventForm
class TrackingEventInline(admin.TabularInline):
#form = MyForm
#formset = MyFormSet
model = TrackingEvent
extra = 0
#readonly_fields = ['datetime', 'event_type', 'note']
def has_add_permission(self, request):
return False
class AddTrackingEventInline(admin.TabularInline):
model = TrackingEvent
extra = 0
def has_change_permission(self, request, obj=None):
return False
def queryset(self, request):
return super(AddTrackingEventInline, self).queryset(request).none()
def get_formset(self, request, obj=None, **kwargs):
if obj:
self.form = create_trackingevent_form(obj)
return super(AddTrackingEventInline, self).get_formset(request, obj, **kwargs)
我希望这能帮助其他有同样问题的人。。堆栈溢出线程帮助我实现了以下目标:
如果你有任何问题,请不要犹豫,问问题。好的,我找到了这个:和这个:我会看看我能从那里走到哪里。好的,我找到了这个:和这个:我会看看我能从那里走到哪里。。