1

我在 django 1.11 中的应用程序,带有 django 软盘表格,输入电子邮件地址后 - 没关系,发送邮件。

问题是当没有邮件地址并按“发送”按钮时。

我收到错误:

'ProductDetailView' object has no attribute 'object'

Traceback 说一些关于这条线的看法:

context = super(ProductDetailView, self).get_context_data(**kwargs)

视图.py

class ProductDetailView(PageeditorMixin, DetailView, FormView):
    model = models.Product
    form_class = forms.DownloadLinkForm
    template_name = 'products/product_detail.html'

    def get_success_url(self):
        return reverse('products:detail', args=[self.kwargs['slug'], self.kwargs['pk']])

    def get_context_data(self, **kwargs):
        context = super(ProductDetailView, self).get_context_data(**kwargs)
        context['events'] = self.object.events.all()
        return context

    def get_form_kwargs(self):
        kwargs = super(ProductDetailView, self).get_form_kwargs()
        kwargs['product_pk'] = self.kwargs['pk']
        return kwargs

    def form_valid(self, form):
        form.send_download_links()
        return super(ProductDetailView, self).form_valid(form)

表格.py

from django.core.mail import send_mail
from django.template.loader import render_to_string
import floppyforms as forms

from products import models


class DownloadLinkForm(forms.Form):
    email = forms.EmailField(required=True)
    email_template = 'products/email.html'

    def __init__(self, product_pk, *args, **kwargs):
        super(DownloadLinkForm, self).__init__(*args, **kwargs)
        self.product = self.get_product_object(product_pk)

    def get_product_object(self, product_pk):
        return models.Product.objects.get(pk=product_pk)

    def get_downloads(self):
        return self.product.downloads.all()

    def get_download_links(self):
        list_download_links = []
        for download in self.get_downloads():
            list_download_links.append(models.DownloadLink.objects.create(download_file=download, email=self.cleaned_data['email']))
        return list_download_links

    def send_download_links(self):
        context = {
            'list_download_links': self.get_download_links()
        }
        html_message = render_to_string(self.email_template, context)
        return send_mail('Download link', '', 'mail@mail.com', [self.cleaned_data['email']], html_message=html_message)

编辑

网址:

url(r'^/(?P<slug>[-\w]+)/(?P<pk>[\d]+)$', views.ProductDetailView.as_view(), name='detail'),

模型:

class Product(models.Model):
    title = models.CharField(max_length=500)
    subtitle = models.CharField(max_length=1000, blank=True)
    image = FilerImageField(related_name="image_product")
    logo = FilerImageField(blank=True, null=True, related_name="logo_product")
    events = models.ManyToManyField('events.Event', related_name="products")

追溯

AttributeError at /en/products/next-title-de/2
'ProductDetailView' object has no attribute 'object'
Request Method: POST
Request URL:    http://127.0.0.1:8000/en/products/next-title-de/2
Django Version: 1.11.2
Exception Type: AttributeError
Exception Value:    
'ProductDetailView' object has no attribute 'object'
Exception Location: Path/venv/lib/python3.5/site-packages/django/views/generic/detail.py in get_context_data, line 101
Python Executable:  Path/venv/bin/python
Python Version: 3.5.2
Python Path:    
['Path/www',
 'Path/www',
 'Path/venv/lib/python35.zip',
 'Path/venv/lib/python3.5',
 'Path/venv/lib/python3.5/plat-x86_64-linux-gnu',
 'Path/venv/lib/python3.5/lib-dynload',
 '/usr/lib/python3.5',
 '/usr/lib/python3.5/plat-x86_64-linux-gnu',
 'Path/venv/lib/python3.5/site-packages',
 'Path/venv/src/next',
 'Path/venv/src/page',
 'Path/venv/src/progress',
 'Path/www/../..']
Server time:    Thu, 22 Feb 2018 17:28:16 +0100
Traceback Switch to copy-and-paste view

Path/venv/lib/python3.5/site-packages/django/core/handlers/exception.py in inner
            response = get_response(request) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/core/handlers/base.py in _legacy_get_response
            response = self._get_response(request) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/core/handlers/base.py in _get_response
                response = self.process_exception_by_middleware(e, request) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/core/handlers/base.py in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/views/generic/base.py in view
            return self.dispatch(request, *args, **kwargs) ...
▶ Local vars
/Path/venv/src/page/page/views.py in dispatch
            from page.page import utils
            page = self.lookup_page(self.get_url(kwargs.get('url')))
            if not utils.check_page_permission(self.request.user, page, "view"):
                return HttpResponseForbidden()
        self.is_admin = self.has_page_permissions(request)
        self.is_edit = self.is_admin and 'edit' in request.GET
        return super(PageMixin, self).dispatch(request, *args, **kwargs) ...
    def has_page_permissions(self, request):
        """
        This method is used to check if the user has permissions to use the
        page editor.
        """
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/views/generic/base.py in dispatch
        return handler(request, *args, **kwargs) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/views/generic/edit.py in post
            return self.form_invalid(form) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/views/generic/edit.py in form_invalid
        return self.render_to_response(self.get_context_data(form=form)) ...
▶ Local vars
Path/www/products/views.py in get_context_data
        context = super(ProductDetailView, self).get_context_data(**kwargs) ...
▶ Local vars
Path/venv/src/page/page/views.py in get_context_data
        return super(PageMixin, self).get_context_data(**context) ...
▶ Local vars
Path/venv/lib/python3.5/site-packages/django/views/generic/detail.py in get_context_data
        if self.object: ...
▶ Local vars
4

1 回答 1

2

object属性仅在 中设置get_context_data()SingleObjectMixin由 使用DetailView。此方法可能被多重继承中的类/mixin 之一覆盖。

但是您可以改用该get_object()方法:

def get_context_data(self, **kwargs):
    context = super(ProductDetailView, self).get_context_data(**kwargs)
    context['events'] = self.get_object().events.all()
    return context
于 2018-02-22T16:03:11.483 回答