
Bernardo Augusto García Loaiza
PreguntaTengo el siguiente modelo llamado LodgingOffer, mediante el cual es posible crear una oferta de alojamiento y detallar sus datos:
<code> 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) country = CountryField(blank_label='(Seleccionar país)', verbose_name='Pais') city = models.CharField(max_length=255, blank = False, verbose_name='Ciudad') def __str__(self): return "%s" % self.ad_title pub_date = models.DateTimeField(auto_now_add=True,) 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)
Para este modelo, tengo una vista de detalle llamada
HostingOfferDetailView
LodgingOffer
Un importante objetivo que quiero perseguir y por el cual formulo esta pregunta es que en la vista de detalle de un objeto
LodgingOffer
LodgingOffer
Para este propósito, tengo la función
contact_owner_offer()
Todo esto lo estoy haciendo en la vista de detalle
HostingOfferDetailView
<code> class HostingOfferDetailView(UserProfileDataMixin, LoginRequiredMixin, 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 # LodgingOffer object #lodging_offer_owner = self.get_object() # Get the full name of the lodging offer owner lodging_offer_owner_full_name = self.get_object().created_by.get_long_name() # Get the lodging offer email owner lodging_offer_owner_email = self.get_object().created_by.email # Get the lodging offer title lodging_offer_title = self.get_object().ad_title # Get the user interested email in lodging offer user_interested_email = user.email # Get the user interested full name user_interested_full_name = user.get_long_name() 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
Mi función
contact_owner_offer
<code> def contact_owner_offer(request, lodging_offer_owner_email, user_interested_email, lodging_offer_title): user = request.user print("a", lodging_offer_owner_email, user_interested_email) if user.is_authenticated: print('Send email') mail_subject = 'Interesados en tu oferta' context = { 'lodging_offer_owner_email': lodging_offer_owner_email, # usuario dueño de la oferta TO 'offer': lodging_offer_title, # oferta por la que se pregunta 'user_interested_email': user_interested_email, # usuario interesado en la oferta '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) # email = EmailMessage(mail_subject, message, to=[to_email]) # email.send() # return redirect('articles:article_list')
Esto lo he hecho a modo de prueba y hasta aquí todo resulta como he querido, y el resultado es que cuando entro al URL de detalle de una oferta objeto
LodgingOffer
Lo que deseo es que en mi template de detalle de oferta, tener un botón el cual diga “Contactar al dueño de la oferta” y que cualquier usuario que lo presione, acto seguido se envíe un correo electrónico al dueño de la oferta.
Para esto, he procedido a definir un URL que llame a la función
contact_owner_offer()
El URL, (acorde a mi entendimiento y es aquí en donde reside la duda y el motivo de mi pregunta) lo he definido acorde al número de parámetros que recibe la función
contact_owner_offer()
Tengo el siguiente modelo llamado LodgingOffer, mediante el cual es posible crear una oferta de alojamiento y detallar sus datos:
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) country = CountryField(blank_label='(Seleccionar país)', verbose_name='Pais') city = models.CharField(max_length=255, blank = False, verbose_name='Ciudad') def __str__(self): return "%s" % self.ad_title pub_date = models.DateTimeField(auto_now_add=True,) def get_absolute_url(self): return reverse('host:detail', kwargs = {'slug' : self.slug })
<h1>I assign slug to offer based in ad_title field,checking if slug exist</h1> 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
<h1>Brefore to save, assign slug to offer created above.</h1> 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)
Para este modelo, tengo una vista de detalle llamada HostingOfferDetailView en la cual muestro los datos de una oferta de un objeto LodgingOffer
Un importante objetivo que quiero perseguir y por el cual formulo esta pregunta es que en la vista de detalle de un objeto LodgingOffer yo debo poder contactar al dueño de esa oferta (objeto LodgingOffer - usuario quien lo creó-) para que otro usuario interesado pueda aplicar a ella.
Para este propósito, tengo la función contact_owner_offer() la cual es una función en donde envío un correo electrónico al dueño de esta oferta.
Todo esto lo estoy haciendo en la vista de detalle HostingOfferDetailView de esta manera:
class HostingOfferDetailView(UserProfileDataMixin, LoginRequiredMixin, 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 # LodgingOffer object #lodging_offer_owner = self.get_object() # Get the full name of the lodging offer owner lodging_offer_owner_full_name = self.get_object().created_by.get_long_name() # Get the lodging offer email owner lodging_offer_owner_email = self.get_object().created_by.email # Get the lodging offer title lodging_offer_title = self.get_object().ad_title # Get the user interested email in lodging offer user_interested_email = user.email # Get the user interested full name user_interested_full_name = user.get_long_name() 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
Mi función contact_owner_offer recibe estos parámetros de oferta y envia el correo al dueño de la oferta o quien la publicó, de la siguiente manera:
def contact_owner_offer(request, lodging_offer_owner_email, user_interested_email, lodging_offer_title):
user = request.user
print(“a”, lodging_offer_owner_email, user_interested_email)
if user.is_authenticated:
print(‘Send email’)
mail_subject = ‘Interesados en tu oferta’
context = { 'lodging_offer_owner_email': lodging_offer_owner_email, # usuario dueño de la oferta TO 'offer': lodging_offer_title, # oferta por la que se pregunta 'user_interested_email': user_interested_email, # usuario interesado en la oferta '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) # email = EmailMessage(mail_subject, message, to=[to_email]) # email.send() # return redirect('articles:article_list')
Esto lo he hecho a modo de prueba y hasta aquí todo resulta como he querido, y el resultado es que cuando entro al URL de detalle de una oferta objeto LodgingOffer, se envía un correo electrónico al dueño de dicha oferta.
Lo que deseo es que en mi template de detalle de oferta, tener un botón el cual diga “Contactar al dueño de la oferta” y que cualquier usuario que lo presione, acto seguido se envíe un correo electrónico al dueño de la oferta.
Para esto, he procedido a definir un URL que llame a la función contact_owner_offer() y que sea llamado desde el atributo href de un boton en mi template:
El URL, (acorde a mi entendimiento y es aquí en donde reside la duda y el motivo de mi pregunta) lo he definido acorde al número de parámetros que recibe la función contact_owner_offer()
Esto significa que mi URL debe recibir:
El email del propietario de la oferta
El email del usuario interesado en la oferta
El titulo de la oferta, aunque para esto estoy enviándole el slug de ese título, no se si eso sea correcto
Entonces, acorde a lo anterior, he creado este URL:
<code> url(r'^contact-to-owner/(?P<email>[\w.@+-]+)/from/' r'(?P<interested_email>[\w.@+-]+)/(?P<slug>[\w-]+)/$', contact_owner_offer, name='contact_owner_offer'),
Seguidamente, en mi template, genero un boton html en donde llamo a esta URL enviándole sus respectivos parámetros:
<code> <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>Contactar</span> </a> </div>
Lo que me sucede es que cuando entro al template de detalle de oferta y hago clic en el boton de Contactar referenciando inmediatamente anterior, tengo el siguiente mensaje de error:
<code> 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 779
Lo que no comprendo, es porque me dice que mi URL no espera un argumento llamado email que es en donde le paso el parámetro
email=lodging_offer_owner_email
Agradezco cualquier orientación

Pavla Fuertes
Wow, esto está genial!

Andrés Felipe Martínez Salazar
Tu url tiene que ser asi:
url(r'^contact-to-owner/(?P<lodging_offer_owner_email>[\w.@+-]+)/from/(?P<user_interested_email>[\w.@+-]+)/(?P<lodging_offer_title>[\w-]+)/$',contact_owner_offer, name='contact_owner_offer'),
Y tu template asi:
<div class="contact"> <a class="contact-button"href="{% url 'host:contact_owner_offer' lodging_offer_owner_email=lodging_offer_owner_email user_interested_email=user_interested_email lodging_offer_title=lodgingofferdetail.slug %}"> <img src="{% static 'img/icons/contact.svg' %}"alt=""> <span>Contactar</span> </a> </div>
Por cierto te recomiendo usar nombres mas cortos imagina que alguien mas esta haciendo los templates o alguna otra parte de tu código y tenga que poner todos esos nombres largos, entiendo que el nombre es muy explicito pero seria algo difícil y feo a la vista, has el código mas fácil y limpio, solo tómalo como un consejo o algo que me gusta hacer a mi.

David Toca
Si quieres usar keywords, el nombre de la variable debe coincidir con el del la url, es decir, contact_owner_offer(email, interested_email, slug)