将用户的主键(pk)从上一页传递到当前页面

时间:2017-11-10 18:36:18

标签: django

我正在构建一个评论页面,其中一个吵闹的用户在用户的页面上留下评论(我的用户称为代理)。 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']

1 个答案:

答案 0 :(得分:0)

视图中的这一行毫无用处:

form.agent = Agent.objects.get(pk=pk)

表单实例不像django模型,您不能设置这样的字段属性。为此,您有两个解决方案:

  1. 您可以先从表单中获取对象,然后设置代理并保存对象。因此,请从表单中删除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})
    

    Documentation about the save method in the Django forms

  2. 如果你真的需要在你的表单中有这个agent字段(但因为它是一个隐藏字段,我假设你没有?)你可以传递{{1关键字,如this answerDocumentation)中所述:

    initial