Использование:
Python 3.7.3
django 2.2.5
mysql 5.7.27
У меня определены следующие модели:
class Item(models.Model):
...
asset = models.ForeignKey('Assets', default=None, null=True, on_delete=models.SET_DEFAULT)
...
class Comments(models.Model):
item = models.ForeignKey('Item', default=None, null=True, on_delete=models.CASCADE)
comment = models.TextField(max_length=512, default="", blank=True)
class Assets(models.Model):
...
assettag = models.CharField(db_column='AssetTag', unique=True, max_length=10)
...
Я хочу обновить представление, которое позволит мне обновить поля объекта Item
, а также предоставит способ редактирования comment
или assettag
. Я использую представления на основе классов, и у меня определена следующая форма:
class ItemUpdateForm(forms.ModelForm):
...
Asset = forms.CharField(label="AssetTag",
required=False,
widget=forms.TextInput(attrs={"placeholder":"Item Inventory Tag",
"rows":1,
"cols":7,
}
)
)
...
class Meta:
model = Item
fields = [
...,
'Asset',
...,
]
def clean_Asset(self, *args, **kwargs):
AssetTag = self.cleaned_data.get("Asset")
if len(AssetTag) != 7:
raise forms.ValidationError("AssetTag length incorrect")
if not AssetTag.lower().startswith("dp"):
raise forms.ValidationError("This is not a valid AssetTag")
else:
try:
_asset = Assets.objects.get(assettag = AssetTag)
except Assets.DoesNotExist:
raise forms.ValidationError("Item does not exist")
self.Asset = _asset
return self.Asset
ItemFormSet = forms.inlineformset_factory(Item, Comments, ItemUpdateForm, fields=('Comment',), extra=1)
Представление не является причудливым:
class UpdateView(ObjectMixin, generic.UpdateView):
template_name = some template
form_class = ItemFormSet
ObjectMixin предоставляет некоторые методы, которые я использовал в нескольких представлениях:get_object
, get_success_url
, form_valid
и dispatch
с login_required
декоратором.
Шаблон также очень прост:
{% extends "pages/base.html" %}
{% block content %}
<h1>Update {{item.Asset.assettag}}</h1>
<form action ="." method="POST"> {% csrf_token %}
<table border="1">
{{ form.as_table }}
</table>
<input class="btn btn-success" type="submit" value="Update"/>
<a href="{{ view.get_success_url }}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}
Проблемы:
- В сгенерированной форме будет отображаться (начальное значение) первичный ключ объекта
Assets
, в то время как я хотел бы, чтобы он отображал поле assettag
.
У меня естьпытался сделать:
class Meta:
model = Item
fields = [
...,
'Asset.assettag',
# or
'Asset__assettag',
...,
]
, но, похоже, не работает. Есть ли способ сделать это?
Использование
inlineformset_factory
будет делать то, что я хочу: показывать поля объекта
Comments
, связанного с экземпляром
Item
. Единственная проблема заключается в том, что он будет отображать
ItemUpdateForm
для каждого
Comments
объекта, который ссылается на
Item
(каждая строка в таблице
Comments , связанная с этим экземпляром
Item
)
Например, если у меня есть только один комментарий и в качестве аргумента указано extra=0
, форма будет в порядке. Если объект Item
будет иметь два комментария, то отображаемая страница будет содержать два ItemUpdateForm
с полем Комментарий, вставленным в каждый. Увеличение значения extra
добавит еще ItemUpdateForm
.
Я предполагаю, что мне нужно вставить каждое поле только в один экземпляр ItemUpdateForm
.
.