我正在构建一个评论页面,其中一个吵闹的用户在用户的页面上留下评论(我的用户称为代理)。 Review
模型具有agent
字段,指定与代理的ForeignKey关系。
网址
url(r'^(?P<pk>\d+)/review/$', views.leave_review, name='leave_review'),
要访问leave_review页面的HTML代码:
<form action="{% url 'leave_review' pk=agent.pk %}" method="post">
{% csrf_token %}
<button class="button3"><span>Leave review</span></button>
</form>
离开评论views.py
def leave_review(request, pk):
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
form.agent = Agent.objects.get(pk=pk)
form.save()
return redirect('review_success.html')
else:
form = ReviewForm()
return render(request, 'leave_review.html', {'form': form})
models.py
class Review(models.Model):
# ... Other fields
agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
def save(self, *args, **kwargs):
if self.agent is None: # Set default reference
self.agent = Agent.objects.get(id=1)
super(Review, self).save(*args, **kwargs)
我目前正在收到一个ValueError,Cannot assign "''": "Review.agent" must be a "Agent" instance.
我相信在这种情况下我正确指定了'pk',但它没有被拾取。这有什么不对?
完全引用
Environment:
Request Method: POST
Request URL: http://localhost:8000/agents/2/review/?csrfmiddlewaretoken=CIxNqtEaFjFIfVwmB6SyV2SAF1VuiDgEf3Di7qZoucG4thIn9ixCbe7GO2UuuW85
Django Version: 1.11.5
Python Version: 3.6.2
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'bungol.accounts',
'bungol.databases',
'bungol.coresite',
'bungol.listings',
'django_extensions',
'djstripe']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\core\handlers\exception.py" in inner
41. response = get_response(request)
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Valachio\Google Drive\Bungol\bungolv4\bungol\databases\views.py" in leave_review
69. if form.is_valid():
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\forms\forms.py" in is_valid
183. return self.is_bound and not self.errors
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\forms\forms.py" in errors
175. self.full_clean()
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\forms\forms.py" in full_clean
386. self._post_clean()
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\forms\models.py" in _post_clean
408. self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\forms\models.py" in construct_instance
65. f.save_form_data(instance, cleaned_data[f.name])
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\db\models\fields\__init__.py" in save_form_data
853. setattr(instance, self.name, data)
File "C:\Python 3.6.2 (32bit)\lib\site-packages\django\db\models\fields\related_descriptors.py" in __set__
216. self.field.remote_field.model._meta.object_name,
Exception Type: ValueError at /agents/2/review/
Exception Value: Cannot assign "''": "Review.agent" must be a "Agent" instance.
class ReviewForm(forms.ModelForm):
REVIEWER_TYPE = (
# ... some choices
)
LOCATION = (
# ... some choices
)
STARS = (
# ... some choices
)
reviewer_type = forms.ChoiceField(widget=forms.RadioSelect, choices=REVIEWER_TYPE)
property_type = forms.ChoiceField(widget=forms.RadioSelect, choices=BuyerListing.PROPERTY_TYPE)
number_of_bedrooms = forms.ChoiceField(choices=BuyerListing.BEDS_OPTION)
location = forms.ChoiceField(choices=LOCATION)
stars = forms.ChoiceField(widget=forms.RadioSelect, choices=STARS)
agent = forms.ChoiceField(widget = forms.HiddenInput(), required=False)
class Meta:
model = Review
fields = ['agent', 'reviewer_first_name', 'reviewer_last_name', 'reviewer_email', 'reviewer_type', 'transaction_id', 'location', 'property_type', 'number_of_bedrooms', 'stars', 'content']
答案 0 :(得分:0)
视图中的这一行毫无用处:
form.agent = Agent.objects.get(pk=pk)
表单实例不像django模型,您不能设置这样的字段属性。为此,您有两个解决方案:
您可以先从表单中获取对象,然后设置代理并保存对象。因此,请从表单中删除agent
字段,然后在视图中创建代码:
def leave_review(request, pk):
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
review = form.save(commit=False) # Getting the unsaved `Review` instance from the form
review.agent = Agent.objects.get(pk=pk) # Set the agent on the `Review` instance
review.save() # Finally save the `Review` instance
return redirect('review_success.html')
else:
form = ReviewForm()
return render(request, 'leave_review.html', {'form': form})
如果你真的需要在你的表单中有这个agent
字段(但因为它是一个隐藏字段,我假设你没有?)你可以传递{{1关键字,如this answer(Documentation)中所述:
initial