将多个参数传递给Django URL - 意外的关键字参数

时间:2017-10-10 12:16:29

标签: python django django-views

如何解决此NoReverseMatch错误?

上下文

我想尽可能详细地记录这个问题,以便能够详细说明问题的根源。

我有一个名为LodgingOffer的模型,用于创建住宿优惠并详细说明其信息

class LodgingOffer(models.Model):

    # Foreign Key to my User model      
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    ad_title = models.CharField(null=False, blank=False,
        max_length=255, verbose_name='Título de la oferta')

    slug = models.SlugField(max_length=100, blank=True)

    # ... Another fields ...

    def __str__(self):
        return "%s" % self.ad_title

    def get_absolute_url(self):
        return reverse('host:detail', kwargs = {'slug' : self.slug })

# I assign slug to offer based in ad_title field,checking if slug exist
def create_slug(instance, new_slug=None):
    slug = slugify(instance.ad_title)
    if new_slug is not None:
        slug = new_slug
    qs = LodgingOffer.objects.filter(slug=slug).order_by("-id")
    exists = qs.exists()
    if exists:
        new_slug = "%s-%s" % (slug, qs.first().id)
        return create_slug(instance, new_slug=new_slug)
    return slug

# Brefore to save, assign slug to offer created above.
def pre_save_article_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = create_slug(instance)

pre_save.connect(pre_save_article_receiver, sender=LodgingOffer)

对于这个模型,我有一个名为HostingOfferDetailView的DetailView。

我想要追求的一个重要目标,我问这个问题的是,在LodgingOffer对象的详细视图中,我应该能够联系该商品的所有者(对象LodgingOffer - 创建它的用户 - )以便其他感兴趣的用户可以申请。

我希望在LodgingOffer对象的详细视图中能够联系商品所有者(对象LodgingOffer - 创建它的用户 - )以便其他感兴趣的用户可以申请

为此目的,我有contact_owner_offer()功能,是我向此优惠的所有者发送电子邮件的地方。

我正在使用HostingOfferDetailView详情视图完成所有操作:

class HostingOfferDetailView(DetailView):
    model = LodgingOffer
    template_name = 'lodgingoffer_detail.html'
    context_object_name = 'lodgingofferdetail'

    def get_context_data(self, **kwargs):
        context = super(HostingOfferDetailView, self).get_context_data(**kwargs)
        user = self.request.user

        # Get the related data offer
        #lodging_offer_owner = self.get_object()
        lodging_offer_owner_full_name = self.get_object().created_by.get_long_name()

        lodging_offer_owner_email = self.get_object().created_by.email

        lodging_offer_title = self.get_object().ad_title
        user_interested_email = user.email
        user_interested_full_name = user.get_long_name()

        # Send to context email of owner offer and user interested in offer
        context['user_interested_email'] = user_interested_email
        context['lodging_offer_owner_email'] = lodging_offer_owner_email

        # Send the data (lodging_offer_owner_email
        # user_interested_email and lodging_offer_title) presented 
        # above to the contact_owner_offer function
        contact_owner_offer(self.request, lodging_offer_owner_email, user_interested_email, lodging_offer_title)

        return context

我的contact_owner_offer()功能会收到这些优惠参数,并向优惠所有者或发布商发送电子邮件,如下所示:

def contact_owner_offer(request, lodging_offer_owner_email, user_interested_email, lodging_offer_title):
    user = request.user
    if user.is_authenticated:
        # print('Send email')
        mail_subject = 'Interest in your offer'

        context = {
            'lodging_offer_owner_email': lodging_offer_owner_email,
            # User owner offer - TO send email message

            'offer': lodging_offer_title,
            # offer for which a user asks 

            'user_interested_email': user_interested_email,
            # Interested user offer

            'domain': settings.SITE_URL,
            'request': request
        }

        message = render_to_string('contact_user_own_offer.html', context)
        #to_email = lodging_offer_owner.email,

        send_mail(mail_subject, message, settings.DEFAULT_FROM_EMAIL,
                  [lodging_offer_owner_email], fail_silently=True)

我已经做了这个测试,到目前为止一切都是我想要的,结果是当我输入详细商品对象LodgingOffer的网址时,会向该商品的所有者发送一封电子邮件

我希望优惠详情模板有一个按钮,其中包含"联系优惠所有者" ,当任何按下它的用户向所有者发送电子邮件时提议。

为此,我为contact_owner_offer()函数定义了一个网址,并在模板中按钮的href属性上有一个链接。

网址(根据我的理解,这是我的问题存在疑问和原因)我根据contact_owner_offer()函数接收的参数数量来定义它。

这意味着我的网址必须收到:

  • 优惠所有者的电子邮件地址
  • 对优惠感兴趣的用户的电子邮件地址
  • 优惠的标题,虽然为此我也是 向你发送那个标题的slu ,,我不知道这是否正确

因此,根据上述内容,我已创建此网址:

url(r'^contact-to-owner/(?P<email>[\w.@+-]+)/from/'
        r'(?P<interested_email>[\w.@+-]+)/(?P<slug>[\w-]+)/$',
        contact_owner_offer, name='contact_owner_offer'),

然后,在我的模板中,我生成一个html按钮,我在其中调用此URL,向他们发送各自的参数,这些参数期望:

<div class="contact">
    <a class="contact-button" href="{% url 'host:contact_owner_offer' email=lodging_offer_owner_email interested_email=user_interested_email slug=lodgingofferdetail.slug %}">
        <img src="{% static 'img/icons/contact.svg' %}" alt="">
        <span>Contact owner offer</span>
    </a>
</div>

当我输入优惠详情模板并点击上方的联系所有者优惠参考按钮时,我会收到以下错误消息:

 TypeError: contact_owner_offer() got an unexpected keyword argument 'email'
[10/Oct/2017 01:04:06] "GET /host/contact-to-owner/botibagl@gmail.com/from/ces@ces.edu.co/apartacho/ HTTP/1.1" 500 77979  

我的追溯就在这里

Traceback:

File "/home/bgarcial/.virtualenvs/hostayni/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  42.             response = get_response(request)

File "/home/bgarcial/.virtualenvs/hostayni/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/bgarcial/.virtualenvs/hostayni/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

Exception Type: TypeError at /host/contact-to-owner/botibagl@gmail.com/from/botibagl@gmail.com/apartacho/
Exception Value: contact_owner_offer() got an unexpected keyword argument 'email'

我不明白,是因为它告诉我我的网址不等待名为email的参数,这是我通过按钮传递参数email=lodging_offer_owner_owner_email的地方在模板中。

我感谢任何指导 最诚挚的问候

更新

根据@RajKris@Daniel建议,我稍微更改了我的网址正则表达式,指定了我传递的关键字参数的名称。 URL保持这种方式:

url(r'^contact-to-owner/(?P<lodging_offer_owner_email>[\w.@+-]+)/from/'
        r'(?P<interested_email>[\w.@+-]+)/(?P<slug>[\w-]+)/$',
        contact_owner_offer,
        name='contact_owner_offer'
    ),

这意味着,我正在命名url参数的方式与我contact_owner_offer()接收的参数的命名方式相同。

当我输入优惠详情模板并点击联系所有者优惠参考按钮时,我收到NoReverseMatch错误

Template error:
In template /home/bgarcial/workspace/hostayni_platform/hosts/templates/lodgingoffer_detail.html, error at line 193
   Reverse for 'contact_owner_offer' with arguments '()' and keyword arguments '{'email': 'botibagl@gmail.com', 'interested_email': 'botibagl@gmail.com', 'slug': 'apartacho'}' not found. 1 pattern(s) tried: ['host/contact-to-owner/(?P<lodging_offer_owner_email>[\\w.@+-]+)/from/(?P<interested_email>[\\w.@+-]+)/(?P<slug>[\\w-]+)/$']   183 :                                </tr>
   184 :                                <tr>
   185 :                                    <td>{{ lodgingofferdetail.room_value }}</td>
   186 :                                    <td>{{ lodgingofferdetail.additional_description }}</td>
   187 :                                    <td>{{ lodgingofferdetail.lodging_offer_owner_email }}</td>
   188 :                                </tr>
   189 :                            </tbody>
   190 :                        </table>
   191 :                    </div>
   192 :                    <div class="contact">
   193 :                        <a class="contact-button" href=" {% url 'host:contact_owner_offer' email=lodging_offer_owner_email interested_email=user_interested_email slug=lodgingofferdetail.slug %} ">
   194 :                            <img src="{% static 'img/icons/contact.svg' %}" alt="">
   195 :                            <span>Contactar</span>
   196 :                        </a>
   197 :                    </div>

一般回溯在这里:

File "/home/bgarcial/.virtualenvs/hostayni/lib/python3.6/site-packages/django/urls/resolvers.py" in _reverse_with_prefix
  392.             (lookup_view_s, args, kwargs, len(patterns), patterns)

Exception Type: NoReverseMatch at /host/lodging-offer/apartacho/
Exception Value: Reverse for 'contact_owner_offer' with arguments '()' and keyword arguments '{'email': 'botibagl@gmail.com', 'interested_email': 'botibagl@gmail.com', 'slug': 'apartacho'}' not found. 1 pattern(s) tried: ['host/contact-to-owner/(?P<lodging_offer_owner_email>[\\w.@+-]+)/from/(?P<interested_email>[\\w.@+-]+)/(?P<slug>[\\w-]+)/$']

如何解决此NoReverseMatch错误?

2 个答案:

答案 0 :(得分:1)

在URL正则表达式中,您必须指定您传递的kyword arg的名称:

url(r'^contact-to-owner/(?P<email1>[\w.@+-]+)/from/' r'(?P<email1>[\w.@+-]+)/(?P<email3>[\w-]+)/$', contact_owner_offer, name='contact_owner_offer'),

这里提到:

Django Doc

答案 1 :(得分:1)

为什么不使用带有params的简单网址?

e.g。 &#34;接触到所有者/所有者电子邮件= XXX&安培;用户电子邮件= XXX&安培;标题= XXX&#34;