Как решить проблему TypeError: Direct assignment to the reverse side of a related set is prohibited ошибку, вызванную полем ForeignKey?
Я пытаюсь массово добавить строки в один из классов моей модели, но не могу этого сделать. Когда я загружаю одну строку информации с помощью моей средней формы, она работает. Эта ошибка стала возникать после добавления отношения foreignkey в моем Uptake model
, которое ссылается на мой Medium model
.
models.py
class Medium(models.Model):
researcher = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name="medium_researcher")
description = models.TextField(null=True, blank=True)
class Uptake(models.Model):
project_type = models.CharField(max_length=10, null=True, blank=True)
medium = models.ForeignKey(Medium, on_delete=models.CASCADE, blank=True, null=True, related_name="uptake_medium")
views.py
from database.utils import get_context, bulkupload
def medium(request):
#We receive bulk upload for medium
if 'bulkupload' in request.POST:
bulkupload(0, list(range(3, 1000, 1)), slice(6, -1), request, Medium, MODEL_HEADERS)
context, MODEL_HEADERS=get_context(request, Medium, MediumForm)
errormessage:
File "C:\dir\Programs\Python\Python310\lib\site-packages\django\db\models\fields\related_descriptors.py", line 606, in __set__
raise TypeError(
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use uptake_medium.set() instead.
Traceback:
O:dir\database\views.py, line 33, in medium
bulkupload(0, list(range(3, 1000, 1)), slice(6, -1), request, Medium, MODEL_HEADERS)
Local vars
O:dir\database\utils.py, line 100, in bulkupload
r = datatable(**appendrow)
Кроме того, я обнаружил, что моя модель Medium содержит заголовки столбцов, такие как uptake_medium, from [f.name for f in Medium._meta.get_fields()]
, но эти столбцы не отображаются в фактической базе данных db.sqlite3. Являются ли эти столбцы foreignkey скрытым полем? Похоже, я больше не могу загрузить простой Medium без добавления связанной информации о Uptake? Я нашел много тем, связанных с этим, но не знаю, как я могу реализовать их в моей функции bulkupload. Для полноты картины я размещу этот код ниже.
def bulkupload(worksheetno, rows_to_check, columns_to_check, request, datatable, MODEL_HEADERS):
"""
worksheetno is denoted from 0 onwards, 0 indicates first sheet
rows_to_check, for example list(range(3, 1000, 1)) to start on row 3 and proceed downwards. If no data in row, loop breaks
columns_to_check, for example [6:-1], this will start at column 6
request, DJANGO request, should be included to get user information and media_file
datatable represents the table to which the data needs to be uploaded
MODEL_HEADERS is headers of the model taken from datatable earlier on
Returns context and model headers to view latest model data after upload
"""
excel_file = request.FILES["media_file"]
# you may put validations here to check extension or file size
wb = openpyxl.load_workbook(excel_file, data_only=True)
worksheet = wb.worksheets[worksheetno]
#Create list of lists to insert (lists keep order)
rows = []
infiniterows=True
while infiniterows:
for i in rows_to_check:
print(i)
R = [None if (item == '#N/A' or item == "na") else item for item in [cell.value for cell in worksheet[i]][columns_to_check]]
if R != [None] * len(R):
rows.append(R)
else:
infiniterows=False
break
#for every row insert list to database
for i in rows:
appendrow={}
for m, k in zip(MODEL_HEADERS[1:], i):
if m == "researcher":
appendrow[m] = request.user
print(m)
print(request.user)
else:
appendrow[m] = k
print("irrelevant")
r = datatable(**appendrow)
try:
r.save()
print("succesful upload")
except IntegrityError as e:
if 'unique constraint' in e.args[0]:
print("row already existed")
Any help is appreciated :)!