Я новичок в Django и использую этот проект, чтобы изучить его. Я могу сохранить запись журнала, но связь "многие ко многим" не работает.
В этом представлении «создание» отображается правильная форма, включая поле с множественным выбором со всеми перечисленными криптовалютами (из модели криптографии). При отправке формы записи «многие-ко-многим» не сохраняются, но Журнал сохраняет отлично.
Я нашел кучу разных ответов на этот вопрос, некоторые относятся к python 2.7, но это самый простой метод, основанный на [документации Django] [1]. Любая помощь приветствуется.
Кроме того, отношения отлично работают в разделе администратора, поэтому я думаю, что это как-то связано с формами и / или просмотром и сохранением.
models.py
from django.db import models
from crypto.models import Crypto as CryptoModel
class Journal(models.Model):
title = models.CharField(max_length=200, help_text='Journal Title', blank=False, null=False)
content = models.TextField(max_length=2000, help_text='Journal Content (HTML OK)', blank=False, null=False)
crypto_id = models.ManyToManyField(CryptoModel, blank=True)
created = models.DateTimeField(help_text='Created', auto_now_add=True, null=True)
def __str__(self):
return self.title ## String for representing the Model object, usually name field or title
forms.py
from django.forms import ModelForm, ModelMultipleChoiceField, widgets
from journal.models import Journal as JournalModel
from crypto.models import Crypto as CryptoModel
class JournalForm(ModelForm):
# select multiple items box
cryptos = ModelMultipleChoiceField(widget=widgets.SelectMultiple(attrs = {'size': 30}), queryset=CryptoModel.objects.all())
class Meta:
model = JournalModel
fields = [
"title",
"content",
]
labels = {
'title': 'Journal Title',
}
required = [
"title", # same as model
"content", # same as model
]
views.py
from journal.forms import JournalForm
from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from journal.models import Journal as JournalModel
def Create(request):
if request.method == "POST":
form = JournalForm(request.POST) # form instance
context = {'form': form} # if errors, keep the form data on next page load
journal = form.save(commit=False) # False needed for many-to-many
journal.title = form.cleaned_data["title"]
journal.content = form.cleaned_data["content"]
journal.created = timezone.now()
journal.save() # save the form journal data, now we have a PK
form.save_m2m() # save the 'form' using ManytoMany method
return HttpResponseRedirect('/journal/')
form = JournalForm()
context = {'form': form}
return render(request, 'journal/create.html', context)
models.py 2
from django.db import models
from crypto.models import Crypto
class Journal(models.Model):
title = models.CharField(max_length=200, help_text='Journal Title', blank=False, null=False)
content = models.TextField(max_length=2000, help_text='Journal Content (HTML OK)', blank=False, null=False)
crypto_id = models.ManyToManyField(Crypto, blank=True)
created = models.DateTimeField(help_text='Created', auto_now_add=True, null=True)
def __str__(self):
return self.title ## String for representing the Model object, usually name field or title
forms.py 2
from django.forms import ModelForm, ModelMultipleChoiceField, widgets
from journal.models import Journal
from crypto.models import Crypto
class JournalForm(ModelForm):
# select multiple items box
cryptos = ModelMultipleChoiceField(widget=widgets.SelectMultiple(attrs = {'size': 30}), queryset=Crypto.objects.all())
class Meta:
model = JournalModel
fields = [
"title",
"content",
"cryptos",
]
views.py 2
from journal.forms import JournalForm
from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from journal.models import Journal
def Create(request):
if request.method == "POST":
form = JournalForm(request.POST) # form instance
context = {'form': form} # if errors, keep the form data on next page load
journal = form.save(commit=False) # False needed for many-to-many
journal.created = timezone.now()
journal.save() # save the form journal data, now we have a PK
journal.crypto_id.set(form.cleaned_data.get("cryptos")) # must be after "save"
form.save_m2m() # save the 'form' using ManytoMany method
return HttpResponseRedirect('/journal/')
form = JournalForm()
context = {'form': form}
return render(request, 'journal/create.html', context)
Вы назвали поля своей модели и формы по-разному; Django не может знать, что они относятся к одному и тому же полю. Имя формы - crypos
- правильное, вы должны переименовать поле вашей модели в это.
Кроме того, вы не указали поле в списке fields
, поэтому Django даже не будет пытаться установить его в модели.
Обратите внимание, что, по вашему мнению, вам не нужно устанавливать заголовок или контент, это то, что form.save
уже делает для вас.
надеюсь, что это решит вашу проблему, но эта строка после сохранения экземпляра журнала journal.crypto_id.set (form.cleaned_data.get ("криптовалюта"))
Спасибо, Абдулла, добавив "journal.crypto_id.set (form.cleaned_data.get (" cryptos "))" в VIEW, проблема была устранена. Дополнительное примечание: это должно быть место после сохранения формы «журнала», но до сохранения многих ко многим.
Я обновил разделы "models.py 2", "forms.py 2" и "views.py 2" выше. Это рабочий код.
всегда пожалуйста. да, но это после journal.save (). и установить не нужно вызывать save () из формы.
Спасибо за ответ. Я внес предложенные вами изменения и разместил новый код как «****. Py 2». К сожалению, это не повлияло на результат, «Многие ко многим» не сохраняет, но отлично работает в разделе «Администратор». Есть другие идеи?