django customuser matching query does not exist - django

I think it originates in this view, since it's being transfered to the home view (see below):
#login_required
def HomePage(request):
if request.user.get_profile().phone == "":
return HttpResponseRedirect('/phone')
else:
add_list = add.objects.all()
ctx = {'last_login':request.session.get('social_auth_login_backend')}
return render_to_response("homepage.html", {'add_list': add_list, 'ctx':ctx}, context_instance=RequestContext(request))
And the model:
class customuser(models.Model):
last_login = models.DateTimeField(blank=True, null=True)
is_active = models.BooleanField()
nickname = models.CharField(max_length=255)
regdate = models.DateField(auto_now=True)
phone = models.CharField(max_length=255)
user = models.OneToOneField(User)
city = models.ForeignKey(locations, null=True)
def __str__(self):
return "%s user " % self.user
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = customuser.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
class Admin:
pass

I'm not sure if this is the cause of you're problem, but the context dictionary that you're passing to your template looks wrong. The view should probably be re-written -
def HomePage(request):
if request.user.get_profile().phone == "":
return HttpResponseRedirect('/phone')
else:
ctx = {'last_login':request.session.get('social_auth_login_backend'),
'add_list': add.objects.all()}
return render(request, "homepage.html", ctx)

Related

How can I access object in Mixin via dispatch?

So I am trying to use Mixin, and the aim is to check if the requester is the owner of the object (owner is a field in my model).
However, I am unable to do such a thing, with a result of 'TweetsUpdateView' object has no attribute 'object', what is wrong in my code?
My models
class Tweets(models.Model):
description = models.TextField(blank=True, null=False, default="", max_length=255)
createdAt = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updatedAt = models.DateTimeField(auto_now=True)
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name="owner_tweets_set",
)
user_likes = models.ManyToManyField(settings.AUTH_USER_MODEL)
My view
class OwnerRequiredMixin(UserPassesTestMixin):
def dispatch(self, request, *args, **kwargs):
if self.object.owner != self.request.user:
return HttpResponseForbidden()
return super(OwnerRequiredMixin, self).dispatch(request, *args, **kwargs)
class TweetsUpdateView(
LoginRequiredMixin,
OwnerRequiredMixin,
UpdateView,
):
model = Tweets
# fields = ["description"]
# template_name = "tweets_form.html"
template_name_suffix = "_form"
form_class = TweetForm
def form_invalid(self, form):
print("form is invalid")
return HttpResponse("form is invalid.. this is just an HttpResponse object")
# slug_field = "id"
# slug_url_kwarg = "tweet_id"
# success_url = reverse_lazy("tweets:twitter")
success_url = reverse_lazy("tweets:twitter")
you can access objects by using self.object = self.get_object()
as it hasn't been called yet

Django change <a> tag on template depending on a condition

I have posts with the option of saving it. The view works properly but I can't see the change in the button. I want that when it is not saved by a user the button says "Save post" and when it is already saved the button should say "unsave". I'm getting problems with this last part. Here part of the code.
views.py
def post(request):
posts = Post.objects.all().order_by("-date_created")
return render(request, "post/food-feed.html", {"posts": posts})
def save_post(request, pk):
post = get_object_or_404(Post, id=pk)
if post.favorite_posts.filter(id=request.user.id).exists():
post.favorite_posts.remove(request.user)
else:
post.favorite_posts.add(request.user)
return HttpResponseRedirect(request.META["HTTP_REFERER"])
template
Save post
urls.py
path("post/<int:pk>/save", views.save_post, name="save-post")
forms.py
class UserSignupForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
def clean_username(self):
username = self.cleaned_data["username"].lower()
if not re.match(r"^[A-Za-z0-9_]+$", username):
raise forms.ValidationError(
"Sorry, your username must only contain letters, numbers and underscores."
)
elif (
User.objects.exclude(pk=self.instance.pk).filter(username=username).exists()
):
raise forms.ValidationError(f"Username {username} is already in use.")
else:
return username
models.py
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=80)
slug = models.SlugField(max_length=250, null=True, blank=True)
post_description = models.TextField(max_length=140, null=True, blank=True)
date_created = models.DateTimeField(default=timezone.now)
date_updated = models.DateTimeField(auto_now=True)
main_image = models.ImageField(upload_to="post_pics")
is_recipe = models.BooleanField()
ingredients = models.TextField(blank=True, null=True)
recipe_description = models.TextField(blank=True, null=True)
cooking_time = models.CharField(max_length=20, blank=True, null=True)
likes = models.ManyToManyField(User, related_name="post_likes")
loves = models.ManyToManyField(User, related_name="post_loves")
drooling_faces = models.ManyToManyField(User, related_name="post_drooling_faces")
favorite_posts = models.ManyToManyField(
User, related_name="favorite_posts", default=None, blank=True
)
def clean(self, *args, **kwargs):
if (
(self.is_recipe and self.ingredients == None)
or (self.is_recipe and self.ingredients == None)
or (self.is_recipe and self.recipe_description == None)
or (self.is_recipe and self.cooking_time == None)
):
raise ValidationError("You need to complete the recipe fields!")
if not self.slug:
slug_title = slugify(self.title)
slug_date = slugify(self.date_created)
self.slug = f"{slug_title}-{slug_date}"
super().clean(*args, **kwargs)
class Meta:
ordering = ("-date_created",)
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse("post-detail", kwargs={"slug": self.slug})
def like_count(self):
return self.likes.count()
def love_count(self):
return self.loves.count()
def droolingface_count(self):
return self.drooling_faces.count()
Each post is shown in the feed-food template with user image, user username, date, photo, title, likes, description and THE SAVE BUTTON
What do I need to add to make the statement work?
You can do using queryset anotation or custom filter tag.
I don't know your models. but you can annotate is_favorite something like this in post view:
from django.db.models import Exists, OuterRef
Post.objects.annotate(
is_favorite=Exists(
Favorite.objects.filter(user=user, product_id=OuterRef('pk'))
)
)
in template:
{% if post.is_favorite %}
save
{% else %}
unsave
{% endif %}

Trying to change new_manager.user.is_employee = False and set it as new_manager.user.is_manager = True , but not working

Upon converting a user into a manager, I need to set 'is_employee = False' and 'is_manager = True'. The process appears to be quite straightforward, but I can't get it to work.
models.py
class User(AbstractUser):
is_admin = models.BooleanField(default=False)
is_employee = models.BooleanField(default=True)
is_manager = models.BooleanField(default=False)
def __str__(self):
return f'{self.first_name} {self.last_name} as {self.username}'
class Manager(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user_profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
business_unit = models.OneToOneField(BusinessUnit, on_delete=models.SET_NULL, null=True)
previous_business_units = models.CharField(max_length=100, default=None, blank=True, null=True)
manager_description = models.TextField(blank=True, null=True)
manager_created_date = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
views.py
#login_required
#admin_required
def manager_create_view(request):
form = ManagerCreationForm()
if request.method == 'POST':
form = ManagerCreationForm(request.POST)
if form.is_valid():
new_manager = form.save(commit=False)
group = Group.objects.get(name='Manager')
new_manager.user.groups.add(group)
new_manager.user.is_employee = False
new_manager.user.is_manager = True
new_manager = form.save()
new_manager = form.cleaned_data.get('user')
messages.success(request, f'{new_manager} is now a Manager!')
return redirect ('list-managers')
messages.error(request, 'Something went wrong, please check the hilighted field(s)')
context = {
'title': 'Create Manager',
'form': form
}
return render(request, 'managers/manager-form.html', context)
I tried using signals as well but, no luck.
signals.py
from django.db.models.signals import post_save
from accounts.models import User, Manager
from django.dispatch import receiver
#receiver(post_save, sender=Manager)
def change_user_type(sender, instance, created, **kwargs):
if created:
instance.user.is_manager = True
instance.user.is_employee = False
Trying to learn on my own, so any help would be greatly appreciated! :)
You need to save the user of the manager, not only the manager itself, so:
#login_required
#admin_required
def manager_create_view(request):
form = ManagerCreationForm()
if request.method == 'POST':
form = ManagerCreationForm(request.POST)
if form.is_valid():
new_manager = form.save() # 🖘 save the manager object
group = Group.objects.get(name='Manager')
user = new_manager.user
user.groups.add(group)
user.is_employee = False
user.is_manager = True
user.save() # 🖘 save the user object
messages.success(request, f'{user} is now a Manager!')
return redirect('list-managers')
messages.error(request, 'Something went wrong, please check the hilighted field(s)')
context = {
'title': 'Create Manager',
'form': form
}
return render(request, 'managers/manager-form.html', context)

Trying to add slug to end of get_absolute_url function in models (Django)

I have a function in my Post model, a get_absolute_url which is a reverse for 'post-detail', it has kwargs for primary key , how do i add another for slug; which is in my Profile model.
At the moment I'm getting error :
NoReverseMatch at /post/26/tested123/update/
Reverse for 'post-detail' with keyword arguments '{'pk': 26}' not found. 1 pattern(s) tried: ['post/(?P[0-9]+)/(?P[-a-zA-Z0-9_]+)/$']
This error occurs when I click the update button on my update post page
feed model
feed/models.py
class Post(models.Model):
description = models.TextField(max_length=255)
pic = models.ImageField(upload_to='path/to/img', blank=True)
date_posted = models.DateTimeField(default=timezone.now)
user_name = models.ForeignKey(User, on_delete=models.CASCADE)
tags = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.description
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
profile model
users/models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.png', upload_to='profile_pics')
slug = AutoSlugField(populate_from='user')
bio = models.CharField(max_length=255, blank=True)
friends = models.ManyToManyField('Profile', blank=True)
def __str__(self):
return str(self.user.username)
def get_absolute_url(self):
return "/users/{}".format(self.slug)
views.py
#login_required
def post_detail(request, pk, slug):
post = get_object_or_404(Post, pk=pk)
user = request.user
is_liked = Like.objects.filter(user=user, post=post)
if request.method == 'POST':
form = NewCommentForm(request.POST)
if form.is_valid():
data = form.save(commit=False)
data.post = post
data.username = user
data.save()
return redirect('post-detail', pk=pk, slug=slug)
else:
form = NewCommentForm()
return render(request, 'feed/post_detail.html', {'post':post, 'is_liked':is_liked, 'form':form})
views.py
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = ['description', 'pic', 'tags']
template_name = 'feed/create_post.html'
def form_valid(self, form):
form.instance.user_name = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.user_name:
return True
return False
Your get_absolute_url in Post doesn't have slug in kwargs or I'm missing something? 'slug': self.user_name.profile.slug

"Todos.user" must be a "UserProfile" instance

Getting Error "Todos.user" must be a "UserProfile" instance. can someone explain why?
I want users in Todos should point to UserProfile and whatever I save in Todos should be displayed in /profile/ ?
class UserProfile(models.Model):
user = models.OneToOneField(User)
birth =models.DateField()
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Todos(models.Model):
user = models.ForeignKey(UserProfile)
title = models.CharField(max_length=100)
created = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
def __unicode__(self):
return unicode(self.user)
Form
class todosform(ModelForm):
title = forms.CharField(label=(u'Todo'))
created = forms.DateField(label=(u'Date'))
start_time = forms.TimeField(label=(u'Start Time'))
end_time = forms.TimeField(label=(u'End Time'))
#user = forms.CharField(label=(u'username')
class Meta:
model = Todos
exclude=('user',)
#url todo url(r'^todo/$', 'registration.views.todo'),
def todo(request):
if request.user.is_authenticated():
Todos.objects.filter(user=request.user)
if request.method == 'POST':
form =formtodos(request.POST)
if form.is_valid():# All validation rules pass
todoss = form.save(commit=False)
todoss.user = request.user
form.save()
return HttpResponseRedirect('/profile/')
else:
form = formtodos()
context = {'form':form}
return render_to_response('todo.html', context, context_instance=RequestContext(request))
#url profile url(r'^profile/$', 'registration.views.Profile'),
#login_required # decorator to check if request login
def Profile(request):
if not request.user.is_authenticated(): #if user not logged in
return HttpResponseRedirect('/login/')
#model = request.user.todos_set.all().order_by('created')[:7]
#u = Todos.objects.filter(created_by = request.user).get(pk=user)
registration = request.user.get_profile
context = {'registration':registration }
return render_to_response('profile.html',context,context_instance=RequestContext(request))
Your user field on Todos is a ForeignKey to UserProfile, not User. request.user is an instance of User. You could to this:
todoss.user = request.user.get_profile()