Django auto fill recipient in Django_messages - python

I'm building a job board and I'm using django_messages for private messages.
It works great but I want to auto fill the recipient form field with the username and I don't know why.
Some thoughts?
This is the view which I have candidates that applied for a job position. When I click send message, I need to auto fill the recipient field.
#views.py
class Screening(generic.DetailView):
model = Job
template_name = 'dashboard/screening.html'
def get_context_data(self, **kwargs):
context = super(Screening, self).get_context_data(**kwargs)
context['candidate_list'] = self.object.applied_to.all().order_by('candidate')
return context
#in the template
{% for candidate in candidate_list %}
{% candidate %}
Send message to this candidate
{% endfor %}
The models
#models.py
class Candidate(models.Model):
user = models.OneToOneField(User, primary_key=True)
birth = models.CharField(max_length=50)
...
class Job(models.Model):
candidate = models.ManyToManyField('Candidate', through='CandidateToJob')
title = models.CharField(max_length=500)
...
class CandidateToJob(models.Model):
job = models.ForeignKey(Job, related_name='applied_to')
candidate = models.ForeignKey(Candidate, related_name='from_user')
STATUS_CHOICES = (
('1', 'Not approved'),
('2', 'Approved'),
('3', 'Hired')
)
status = models.CharField(max_length=2, choices=STATUS_CHOICES)
class Meta:
unique_together = ("candidate", "job")
The django_messages app view to send messages
def compose(request, recipient=None, form_class=ComposeForm,
template_name='djangomessages/compose.html', success_url=None, recipient_filter=None):
if request.method == "POST":
sender = request.user
form = form_class(request.POST, recipient_filter=recipient_filter)
if form.is_valid():
form.save(sender=request.user)
messages.info(request, _(u"Message successfully sent."))
if success_url is None:
success_url = reverse('messages_inbox')
if 'next' in request.GET:
success_url = request.GET['next']
return HttpResponseRedirect(success_url)
else:
form = form_class()
if recipient is not None:
recipients = [u for u in User.objects.filter(**{'%s__in' % get_username_field(): [r.strip() for r in recipient.split('+')]})]
form.fields['recipient'].initial = recipients
return render_to_response(template_name, {
'form': form,
}, context_instance=RequestContext(request))
And the model in django_messages app
class Message(models.Model):
subject = models.CharField(_("Subject"), max_length=120)
body = models.TextField(_("Body"))
sender = models.ForeignKey(AUTH_USER_MODEL, related_name='sent_messages', verbose_name=_("Sender"))
recipient = models.ForeignKey(AUTH_USER_MODEL, related_name='received_messages', null=True, blank=True, verbose_name=_("Recipient"))

Related

Python Django: "Post.author" must be a "User" instance error

I am trying to assign username to author field in Post model , Django spews out the following error:
"Post.author" must be a "User" instance.
model:
class Post(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to='',null=True,blank=True)
image_url = models.CharField(max_length=200,default=None,null=True,blank=True)
date = models.DateTimeField(default=timezone.now)
content = models.TextField()
author = models.ForeignKey(User, null=False, blank=False,on_delete=models.CASCADE)
categories = models.ManyToManyField(Category)
published = models.BooleanField()
def __str__(self):
return self.title
view:
#login_required
def new_post(request):
# Add a new post
if request.method != 'POST':
# No data submitted, create a blank form
form = PostForm()
else:
# Post data submitted, process data
form = PostForm(data=request.POST)
if form.is_valid():
new_post = form.save(commit=False)
new_post.author = request.user.username
new_post.save()
return redirect('elogs:posts')
#Display a blank or invalid form
context = {'form':form}
return render(request,'elogs/new_post.html',context)
form:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','content','image','image_url','published']
widgets = {
'title': forms.Textarea(attrs={'placeholder': 'Title..'}),
'content': forms.Textarea(attrs={'placeholder': 'What is on your mind?'}),
'categories': forms.TextInput()
}
I have solved this error just like this:
from django.contrib.auth import get_user_model
author = models.OneToOneField(get_user_model(),on_delete=models.CASCADE)
You're giving the username instead of the user itself:
new_post.author = request.user.username
A ForeignKey takes an instance of the given Model, User in this case.

Display defferent usernames in django EmailMultiAlternatives template

How to show different username in template body if i want to send email via EmailMultiAlternatives with Django. I have several email receivers.
Here is my code:
models.py:
class User(AbstractUser):
category = models.ForeignKey('news.Category', on_delete=models.CASCADE,
related_name='subscribers', null=True)
class Category(models.Model):
category = models.CharField(unique=True, max_length=255)
class Post(models.Model):
NEWS = 'NEWS'
POST = 'POST'
type_choice = [(NEWS, 'Nowost'), (POST, 'Post')]
author = models.ForeignKey('accounts.Author', on_delete=models.CASCADE)
date_of_creation = models.DateTimeField(auto_now_add=True)
text_content = models.TextField()
rating = models.IntegerField(default=0)
header = models.CharField(max_length=255)
category = models.ManyToManyField(Category, through='PostCategory')
type_of_content = models.CharField(max_length=4, choices=type_choice, default=NEWS)
signals.py
#receiver(m2m_changed, sender=Post.category.through)
def notify_subscribers(sender, instance, action,**kwargs):
if action == 'post_add':
email_of_subscribers = list(instance.category.all().values_list('subscribers__email', flat=True))
html_content = render_to_string(
r'mails_forms/post_created.html',
{'single_news': instance
}
)
msg = EmailMultiAlternatives(
subject=instance.header,
body=instance.text_content,
to=email_of_subscribers
)
msg.attach_alternative(html_content, 'text/html')
msg.send()
template mails_forms/post_created.html
Hello, {{ username }}. New post in your favorite category!
{{ single_news.text_content|truncatechars:50 }}
Open post
You can iterate over subscribers. And instead of values_list('subscribers__email', flat=True) use values('subscribers__email', 'subscribers__username')
#receiver(m2m_changed, sender=Post.category.through)
def notify_subscribers(sender, instance, action,**kwargs):
if action == 'post_add':
subscribers = instance.category.values(
'subscribers__email', 'subscribers__username'
)
for subscriber in subscribers:
html_content = render_to_string(
'mails_forms/post_created.html',
{
'single_news': instance,
'username': subscriber.get("subscribers__username")
}
)
msg = EmailMultiAlternatives(
subject=instance.header,
body=instance.text_content,
to=[subscriber.get("subscribers__email")]
)
msg.attach_alternative(html_content, 'text/html')
msg.send()

Drop down field shows values of all users

I have a form field in Django called Label. My problem is that the field shows the Labels of all users while I only want to show self created labels.
models
class Label(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
tag = models.CharField(max_length=25)
def __str__(self):
return self.tag
class Birthday(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=25, default="")
day = models.DateField()
label = models.ForeignKey(Label, on_delete=models.SET_NULL, default=0, null=True, blank=True)
def __str__(self):
return self.name
forms
class BirthdayForm(forms.ModelForm):
class Meta:
model = Birthday
fields = ('name', 'day', 'label')
class LabelForm(forms.ModelForm):
class Meta:
model = Label
fields = ('tag',)
template
<form method="POST">{% csrf_token %}
<table border="0">
{{ form }}
</table>
<button class="submitButton" type="submit">Submit</button>
</form>
This is the view for this template
view
#login_required
def index(request):
if request.method == "POST":
form = BirthdayForm(request.POST)
if form.is_valid():
birthday = form.save(commit=False)
birthday.user = request.user
birthday.save()
return redirect('index')
else:
#default_labels("Friend", request)
#default_labels("Family", request)
form = BirthdayForm()
birthday = Birthday.objects.filter(user=request.user)
username = request.user
return render(request, 'bd_calendar/index.html', {'form': form, 'birthday': birthday, 'username': username })

How to get manytomanyfield model data in View in Django

models.py
class Account(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
id = models.CharField(max_length=50, unique=True)
pw = models.CharField(max_length=200)
nick = models.CharField(max_length=50, blank=True)
blog = models.URLField(null=True, blank=True)
published_date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.published_date = timezone.now()
self.pw = make_password(self.pw)
super(Account, self).save(*args, **kwargs)
def __str__(self):
return self.id
class Meta:
ordering = ["-published_date"]
class Task(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
account = models.ManyToManyField(Account)
published_date = models.DateTimeField(default=timezone.now)
def publish(self):
self.published_date = timezone.now()
self.save()
forms.py
classAccountForm(forms.ModelForm):
class Meta:
model = NaverAccount
fields = ('id', 'pw', 'nick','blog',)
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ('account',)
task.html
<form action="#" class="form-horizontal" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Save</button>
views.py
def task(request):
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
#1. id = str(from Account model)
#2. pw = str(from Account model)
post.save()
form.save_m2m()
return redirect('task')
else:
form = TaskForm()
context = {'form': form}
return render(request, 'work/task.html', context)
I'm making small task app.
I want to get model data that user select(Account) from template in view.
ex) user can select 'id1', 'id2'.
and I want to get id, pw value in view.
so I can play small task with using id, pw in view
I tried to test some code in view like print(post.account) but can't go further.
1. id = str(from Account model)
2. pw = str(from Account model)

Django raising Type Error "profile() got an unexpected keyword argument 'user'"

I've been working with Django for a short while and today I ran into a problem that for the life of me I can't figure out. I'm trying to load the user's profile which they themselves have saved on a previous step, however when I try to open the page where the profile should be so they can see it and edit it I am getting the error I mentioned.
Here are my views.py
#verified_email_required()
def home(request):
usuario = Perfil.objects.filter(user=request.user)
context = ({"usuario": usuario})
return render(request, "explore/inicioapp.html", context)
#verified_email_required()
def profile(request, id):
instance = get_object_or_404(Perfil, id=id)
form = ProfileForm(instance=instance)
if request.method == "POST":
form = ProfileForm(request.POST, instance=instance)
if form.is_valid():
perfil = form.save(commit=False)
perfil.user = request.user
perfil.save()
return HttpResponseRedirect("/profile/")
context = ({"form", form}, {"datos": instance})
return render(request, "explore/profile.html", context)
models.py
class Perfil(models.Model):
user = models.OneToOneField(User)
Sexo = models.CharField(max_length=100)
Direccion = models.CharField(max_length=100)
CP = models.CharField(max_length=100)
Ciudad = models.CharField(max_length=100)
Estado = models.CharField(max_length=100)
Pais = models.CharField(max_length=100)
Telefono = models.CharField(max_length=100)
Celular = models.CharField(max_length=100)
PaisPasaporte = models.CharField(max_length=100)
NumeroPasaporte = models.CharField(max_length=100)
VigenciaPasaporte = models.DateField(max_length=100)
ContactoEmergencia = models.CharField(max_length=100)
TelefonoEmergencia = models.CharField(max_length=100)
CorreoEmergencia = models.CharField(max_length=100)
Alergias = models.CharField(max_length=500)
forms.py
class ProfileForm(forms.ModelForm):
class Meta:
model = Perfil
exclude = ["user"]
widgets = {
'Sexo': Select(choices=opciones_sexo, attrs={'class': 'selectpicker'}),
'VigenciaPasaporte': forms.DateInput(attrs={'class': 'datepicker'})
}
labels = {
'Sexo': _("Gender"),
'Direccion': _("Address"),
'CP': _("Zip code"),
'Ciudad': _("City"),
'Estado': _("State"),
'Pais': _("Country"),
'Telefono': _("Phone"),
'Celular': _("Cellphone"),
'PaisPasaporte': _("Passport emission country"),
'NumeroPasaporte': _("Passport number"),
'VigenciaPasaporte': _("Passport expiration date"),
'ContactoEmergencia': _("Emergency contact person"),
'TelefonoEmergencia': _("Emergency contact phone"),
'CorreoEmergencia': _("Emergency contact email")
}
def __init__(self, *args, **kwargs):
kwargs.setdefault("label_suffix", "")
super(ProfileForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(ProfileForm, self).clean()
sexoseleccionado = cleaned_data.get("Sexo")
if sexoseleccionado == "none":
raise forms.ValidationError("You must select a gender to continue.")
return cleaned_data
url
url(r'^profile/(?P<user>\d+)$', views.profile, name="profile"),
And finally the HTML link
<a class="btn btn-menu" href="{% url "explore:profile" Perfil.id %}">{% trans "My Profile" %}</a>
Thanks!
Your problem is that your url pattern is passing an argument user, but your view method is defining the argument as id.
url(r'^profile/(?P<user>\d+)$', views.profile, name="profile"),
^^^^
Your view method, however:
#verified_email_required()
def profile(request, id):
^^
It's just a name issue. In the URL for profile you are capturing a "user" variable. But the view itself is expecting an "id" argument. Make these consistent.

Categories