ValueError: <Registration: 749>" needs to have a value for field "id" before this many-to-many relationship can be used
ValueError: <Registration: 749>" needs to have a value for field "id" before this many-to-many relationship can be used
我正在 django 中构建一个比赛注册应用程序,但在 CreateView 通用视图中保存我的模型的 many2many 字段时遇到了问题。我从视图中排除了事件字段,因为它允许您 select 一个事件,而不是让它从 url 中的 slug 自动生成。我能够使用 get_context_data 方法中的 slug 获取基于 URL 的事件对象。我也在 form_valid 方法中尝试了 form.instance.event = event 但它似乎在这里不起作用。我以前没有在 many2many 领域工作过,现在我遇到了麻烦。非常感谢任何帮助。
我收到一个 ValueError:
在可以使用这种多对多关系之前,“”需要为字段 "id" 设置一个值。
views.py
class RegistrationCreateView(CreateView):
model = Registration
fields = ['car_year', 'car_manufacture', 'car_model', 'race_number', 'race_class']
def get_context_data(self, *args, **kwargs):
slug = self.kwargs['slug']
event = Event.objects.get(slug=slug)
context = super().get_context_data(**kwargs)
context['slug'] = slug
context['event'] = event
return context
def form_valid(self, form):
form.instance.driver = self.request.user
try:
event = Event.objects.get(id=self.request.POST['event'])
except:
event = None
print("test")
form.instance.event.add(event)
return super().form_valid(form)
urls.py
from django.urls import path
from . import views
app_name = "events"
urlpatterns = [
path(
route='add/',
view=views.EventCreateView.as_view(),
name='add'
),
path(
route='',
view=views.EventListView.as_view(),
name="list"
),
path(
route='<slug:slug>/',
view=views.EventDetailView.as_view(),
name="detail"
),
path(
route='<slug:slug>/update/',
view=views.EventUpdateVIew.as_view(),
name='update'
),
path(
route="<slug:slug>/register/",
view=views.RegistrationCreateView.as_view(),
name='register'
),
]
models.py
from django.db import models
from django.conf import settings
from autoslug import AutoSlugField
from model_utils.models import TimeStampedModel, TimeFramedModel
from localflavor.us.models import USStateField, USZipCodeField
from django.urls import reverse
class Event(TimeStampedModel, TimeFramedModel):
organizer = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
name = models.CharField("Event Name", max_length=255)
location_name = models.CharField("Event Location", max_length=255)
location_street_address = models.CharField("Event Address", max_length=100)
location_state = USStateField("Event State")
location_city = models.CharField("City", max_length=40)
location_zip = USZipCodeField("Event Zipcode")
description = models.TextField("Event Description")
slug = AutoSlugField("Event Slug",
unique=True, always_update=False, populate_from="name")
registration_start = models.DateField("Pre-Registration Starts", blank=True)
registration_end = models.DateField("Pre-Registration Ends", blank=True)
def __str__(self):
return self.name
def address(self):
full_location = f"""
{self.location_name}
{self.location_street_address}
{self.location_city}, {self.location_state} {self.location_zip}
"""
return(full_location)
def get_absolute_url(self):
return reverse('events:detail', kwargs={'slug': self.slug})
class Registration(TimeStampedModel):
class RaceClass(models.TextChoices):
STOCK_2WD = "S2", "Stock 2 Wheel Drive"
STOCK_AWD = "SA", "Stock All Wheel Drive"
PREP_2WD = "P2", "Prepared 2 Wheel Drive"
PREP_AWD = "PA", "Prepared All Wheel Drive"
MOD_2WD = "M2", "Modified 2 Wheel Drive"
MOD_AWD = "MA", "Modified All Wheel Drive"
CON_2WD = "C2", "Constructors 2 Wheel Drive"
CON_AWD = "C4", "Constructurs 4 Wheel Drive"
driver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
event = models.ManyToManyField(Event)
car_year = models.PositiveIntegerField("Car Year")
car_manufacture = models.CharField("Car Manufacture", max_length=15)
car_model = models.CharField("Car Make", max_length=30)
race_number = models.PositiveIntegerField("Race Number")
race_class = models.CharField("Race Class", choices=RaceClass.choices, default=RaceClass.STOCK_2WD, max_length=50)
def get_absolute_url(self):
return reverse('events:list')
def __str__(self):
return str(self.race_number)
您需要先保存表格,因此您要添加多对多对象的对象会先创建。只有在创建了一个对象之后,您才可以向其中添加许多对象。所以在你的例子中,你需要做这样的事情:
def form_valid(self, form):
form.instance.driver = self.request.user
if form.is_valid():
registration = form.save() # returns the newly created object
registration.event.add(event)
return super().form_valid(form)
我正在 django 中构建一个比赛注册应用程序,但在 CreateView 通用视图中保存我的模型的 many2many 字段时遇到了问题。我从视图中排除了事件字段,因为它允许您 select 一个事件,而不是让它从 url 中的 slug 自动生成。我能够使用 get_context_data 方法中的 slug 获取基于 URL 的事件对象。我也在 form_valid 方法中尝试了 form.instance.event = event 但它似乎在这里不起作用。我以前没有在 many2many 领域工作过,现在我遇到了麻烦。非常感谢任何帮助。
我收到一个 ValueError: 在可以使用这种多对多关系之前,“”需要为字段 "id" 设置一个值。
views.py
class RegistrationCreateView(CreateView):
model = Registration
fields = ['car_year', 'car_manufacture', 'car_model', 'race_number', 'race_class']
def get_context_data(self, *args, **kwargs):
slug = self.kwargs['slug']
event = Event.objects.get(slug=slug)
context = super().get_context_data(**kwargs)
context['slug'] = slug
context['event'] = event
return context
def form_valid(self, form):
form.instance.driver = self.request.user
try:
event = Event.objects.get(id=self.request.POST['event'])
except:
event = None
print("test")
form.instance.event.add(event)
return super().form_valid(form)
urls.py
from django.urls import path
from . import views
app_name = "events"
urlpatterns = [
path(
route='add/',
view=views.EventCreateView.as_view(),
name='add'
),
path(
route='',
view=views.EventListView.as_view(),
name="list"
),
path(
route='<slug:slug>/',
view=views.EventDetailView.as_view(),
name="detail"
),
path(
route='<slug:slug>/update/',
view=views.EventUpdateVIew.as_view(),
name='update'
),
path(
route="<slug:slug>/register/",
view=views.RegistrationCreateView.as_view(),
name='register'
),
]
models.py
from django.db import models
from django.conf import settings
from autoslug import AutoSlugField
from model_utils.models import TimeStampedModel, TimeFramedModel
from localflavor.us.models import USStateField, USZipCodeField
from django.urls import reverse
class Event(TimeStampedModel, TimeFramedModel):
organizer = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
name = models.CharField("Event Name", max_length=255)
location_name = models.CharField("Event Location", max_length=255)
location_street_address = models.CharField("Event Address", max_length=100)
location_state = USStateField("Event State")
location_city = models.CharField("City", max_length=40)
location_zip = USZipCodeField("Event Zipcode")
description = models.TextField("Event Description")
slug = AutoSlugField("Event Slug",
unique=True, always_update=False, populate_from="name")
registration_start = models.DateField("Pre-Registration Starts", blank=True)
registration_end = models.DateField("Pre-Registration Ends", blank=True)
def __str__(self):
return self.name
def address(self):
full_location = f"""
{self.location_name}
{self.location_street_address}
{self.location_city}, {self.location_state} {self.location_zip}
"""
return(full_location)
def get_absolute_url(self):
return reverse('events:detail', kwargs={'slug': self.slug})
class Registration(TimeStampedModel):
class RaceClass(models.TextChoices):
STOCK_2WD = "S2", "Stock 2 Wheel Drive"
STOCK_AWD = "SA", "Stock All Wheel Drive"
PREP_2WD = "P2", "Prepared 2 Wheel Drive"
PREP_AWD = "PA", "Prepared All Wheel Drive"
MOD_2WD = "M2", "Modified 2 Wheel Drive"
MOD_AWD = "MA", "Modified All Wheel Drive"
CON_2WD = "C2", "Constructors 2 Wheel Drive"
CON_AWD = "C4", "Constructurs 4 Wheel Drive"
driver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
event = models.ManyToManyField(Event)
car_year = models.PositiveIntegerField("Car Year")
car_manufacture = models.CharField("Car Manufacture", max_length=15)
car_model = models.CharField("Car Make", max_length=30)
race_number = models.PositiveIntegerField("Race Number")
race_class = models.CharField("Race Class", choices=RaceClass.choices, default=RaceClass.STOCK_2WD, max_length=50)
def get_absolute_url(self):
return reverse('events:list')
def __str__(self):
return str(self.race_number)
您需要先保存表格,因此您要添加多对多对象的对象会先创建。只有在创建了一个对象之后,您才可以向其中添加许多对象。所以在你的例子中,你需要做这样的事情:
def form_valid(self, form):
form.instance.driver = self.request.user
if form.is_valid():
registration = form.save() # returns the newly created object
registration.event.add(event)
return super().form_valid(form)