Я знаю, как решить проблему, с которой я сталкиваюсь. Но дело в том, что я не знаю, почему код ведет себя так.
Поэтому мне нужен кто-то, чтобы объяснить, почему это происходит.
Мне нужно отредактировать TextField с помощью пользовательского ввода и показать новый TextField, и он работает, как и ожидалось, когда изменились и CharField, и TextField, но он не работает, когда изменился только TextField. Кстати, когда изменился только CharField, CharField обновляется.
Позвольте мне поделиться фрагментами. Это не то, что у меня есть в моей кодовой базе.
models.py
class Foo(models.Model):
foo_name = models.CharField(max_length=100)
foo_message = models.TextField(max_length=200)
class Bar(models.Model):
foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
bar_name = models.CharField(max_length=100, unique=True)
bar_message = models.TextField(max_length=200)
forms.py
class BarForm(ModelForm):
class Meta:
model = Bar
fields = ["bar_name", "bar_message"]
views.py
def show_bar(request, foo_name, bar_name):
foo = Foo.objects.get(foo_name__iexact=foo_name)
bar = foo.bar_set.get(bar_name=bar_name)
if request.method == "POST":
form = BarForm(request.POST)
if form.is_valid():
bar.bar_name = form.cleaned_data["bar_name"]
bar.bar_message = form.cleaned_data["bar_message"]
bar.foo = foo
bar.save()
return redirect("bar-show", foo_name, bar.bar_name)
context = {"foo": foo, "bar": bar}
return render(request, "bar_show.html", context)
def edit_bar(request, foo_name, bar_name):
foo = Foo.objects.get(foo_name__iexact=foo_name)
bar = foo.bar_set.get(bar_name=bar_name)
form = BarForm(instance=bar)
context = {"foo": foo, "bar": bar, "form": form}
return render(request, "bar_edit.html", context)
Шаблоны
bar_show.html
<h1>bar_name</h1>
<p>{{ bar.bar_name }}</p>
<h1>bar_message</h1>
<p>{{ bar.bar_message}}</p>
<a href="{% url 'bar-edit' foo.foo_name bar.bar_name %}">edit</a>
bar_edit.html
<form action="{% url 'bar-show' foo.foo_name bar.bar_name %}" method="post">
{{ form.non_field_errors }}
{% csrf_token %}
<p>{{ form.bar_name.errors }} {{ form.bar_name }}</p>
<p>{{ form.bar_message.errors }} {{ form.bar_message }}</p>
<input type="submit" value="edit">
</form>
urls.py
urlpatterns = [
path("/<str:foo_name>/<str:bar_name>/", views.show_bar, name="bar-show"),
path("/<str:foo_name>/<str:bar_name>/edit/", views.edit_bar, name="bar-edit")
]
Что я хочу, чтобы это произошло, и что на самом деле произошло раньше, это:
- только bar_name отредактировано => успешно отредактировано
- только bar_message отредактировано => успешно отредактировано
- оба отредактированы => успешно отредактированы
И это ожидаемое поведение произошло до того, как я добавил unique=True
к bar_name = models.CharField(max_length=100)
.
А теперь, что происходит:
- только bar_name отредактировано => успешно отредактировано
- только bar_message отредактировано => не успешно отредактировано
- оба отредактированы => успешно отредактированы
Когда вы редактировали только bar_message
, отредактированный bar_message
исчезает, а предыдущий bar_message
отображается в bar_show.html.
Чтобы решить эту проблему, все, что мне нужно сделать, это добавить instance=bar
к form = BarForm(request.POST)
.
Я знаю, что благодаря https://djangosnippets.org/snippets/1228/ и Как загрузить экземпляр в Django ModelForms .
Но что я не понимаю, так это то, почему «только bar_message edited => не успешно отредактировано» происходит внезапно после того, как я добавил unique=True
.
Кто-нибудь может мне это объяснить?