I am having a tough time with following code.
{% if object.author == user.username %}
That code is not working neither giving error.
So I have articles app inside my django project. I want to make sure that if a user goes to their own post, then only they should be able to see delete and edit links (I will be placing them inside if block).
The Article model is as follows:
class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
Here
{{user.username}}
{{object.author}}
both are valid django variables.
{{user.username}}
specifies username of current logged in user
{{object.author}}
specifies author of that particular post.
Please help me out to implement with comparison logic of both variables. I am using python 3.6, django 2.1 and django template language.
Your question would be easier to answer if you posted your models (and formatted your text correctly).
I presume that object.author is actually a ForeignKey to the User model. Therefore, you should compare directly with the user, not with the username attribute of the user:
{% if object.author == user %}
Related
I have a Django template where I do queries like this:
{% for post in user.post_auctions_set.all %}
The point for me now is that I only want to display post elements that don't have the Boolean prime = True.
I came across template tags but never really worked with them.
Can smb. give me a hint on how I could setup a filter like?
views.py
def pae(request, pk=None):
if pk:
user = get_user_model().objects.get(pk=pk)
else:
user = request.user
args = {'user': user}
return render(request, 'App/pae.html', args)
models.py
class Post_Auctions(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
...
prime = models.BooleanField(verbose_name="Prime", default=False, editable=True)
Thanks in advance
You could use the if clause form the built-in django template tag set:
{% for post in user.post_auctions_set.all %}
{% if post.prime %}
...
Note: this might not be the best solution, but the only I could think of right know, as I am not too familiar with Django right now. At least, what I've read of somewhere somewhen, is to avoid such template logic whenever possible.
I new to django and I am trying to make a web application. I have this page page image and I want to delete one post when I press the delete button. How can I do that? This is my modal for 'Post' :
class Post(models.Model):
created_date = models.DateTimeField()
title = models.CharField(max_length=100)
profile_image = models.ImageField(upload_to='poze', blank=True, null=True)
text = models.CharField(max_length=1000, default='Nimic', blank=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
I've been looking for delete methods, but I've always found form-only methods and I don't use form. Thank you.
In you html :
Delete
assuming that you are using a for loop :
{% for p in posts %}
In your urls :
path('delete/<post_id>',views.delete_post,name='delete')
In your views :
def delete_post(request,post_id=None):
post_to_delete=Post.objects.get(id=post_id)
post_to_delete.delete()
return HttpResponseRedirect(#name of the view function that returns your posts page)
And that's it
EDIT
This method deletes data from your database directly. So I recommend you add the #login_required decorator to your delete_post view function to protect your post. You can also make it accessible only for admin users or post owners in your html (Example : only users who have staff role can see the delete link)
{% if user.is_staff %}
<a ...>Delete</a>
{% endif %}
You need to pass argument with post id. It would like something like this
p = Post.objects.get(pk=2)
p.delete()
You should create a new field in the database table. Whenever you are deleting the data then you should change the delete field.
class Post(models.Model):
created_date = models.DateTimeField()
title = models.CharField(max_length=100)
profile_image = models.ImageField(upload_to='poze', blank=True, null=True)
text = models.CharField(max_length=1000, default='Nimic', blank=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
delete_flag = models.BooleanField(default=False)
And whenever you are should the data then you should filter the data on the delete flag
Post.objects.filter(delete_flag=False)
Though it is subjective and I don't know you use case, but still as a beginner its better to start with this practice.
Read More
Article 2
I'm working on a project with python-3.6.4 and django-2.0.2. For simplicity, I'm explaining the situation in short. Suppose, there are three apps:- "problems", "solve_activities" and "profiles" having three models(mentioned below) inside them. I have a "DetailView" page for each problem. I want to show if the logged in user has solved the problem or not.
The django template tag that I wanted to do use was something like this:
{% if user.is_authenticated and problem.solved.all.filter(solver={{user.username}}) %}
Here are the above mentioned files:
"problems/models.py":
class Problem(models.Model):
name = models.CharField(max_length=20)
slug = models.SlugField(allow_unicode=True, max_length=100, unique=True)
def __str__(self):
return self.name
def get_absoulte_url(self):
return reverse('problems')
return reverse('problems:problem_detail', kwargs={'slug':self.slug})
I've used the urlpatterns in 'problems/urls.py' as "path('/', views.ProblemDetail.as_view(), name='problem_detail')".
"profiles/models.py"(inherited from auth.models.User):
class User(auth.models.User, auth.models.PermissionsMixin):
def __str__(self):
return self.username
"solve_activities/models.py":
class Solve(models.Model):
problem = models.ForeignKey(Problem, on_delete=models.CASCADE, related_name="solved")
solver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="solved")
I'm only creating this object when the user solves a problem.
Now, my ProblemDetail view on problems/views.py:
class ProblemDetail(generic.DetailView):
model = Problem
template_name = 'problems/problem_detail.html'
And the "problems/problem_detail.html" file where I'm facing the complexity basically:
<h1>{{problem}}</h1>
<h4>Solve Status: {% if user.is_authenticated and problem.solved.all.filter(solver={{user.username}}) %}Solved{% else %}Unsolved{% endif %}</h4>
Again,
{% if user.is_authenticated and problem.solved.all.filter(solver={{user.username}}) %}
is what I want to do, but I couldn't find any useful resource on how to do it correctly.
The error it's raising is:
TemplateSyntaxError at /problems/timus-1000/
Could not parse the remainder: '(solver={{user}})' from 'problem.solved.all.filter(solver={{user}})'
Dont do logic in templates, thats what views are for. Add it to the context and use it in the template.
class ProblemDetail(generic.DetailView):
...
def get_context_data(self, *args, **kwargs):
context = super(ProblemDetail, self).get_context_data()
context["solve_status"] = self.request.user.is_authenticated and context["object"].solved.filter(solver=self.request.user).exists()
return context
then in the template use
{% if solve_status %} ..
Thank you very much for taking your time.
Previously, I posted this question, How to Get Unread Posts for Users.
The problem was: I cannot filter out which article one user has not read while this article has already been read by another user.
I figured out why I cannot do that---- because I have data that I wrote into the database without using Django although I set the reading default for each post to False---- there is simply no record.
Then, I manually set one article to unread to a user in the Admin, everything works, because now in the database there is one record stating that this certain article has not been read by this user.
The problem now is:
How do I set "unread" for every existing article that I have in the database for all existing users?
And how can articles stay unread for every new user unless the new user actually read it?
For your convenience, I copied the codes to here.
My model:
class Posts(models.Model):
title = models.CharField(max_length=255)
content_url = models.URLField(unique=True)
content = models.CharField(max_length=255)
post_date = models.DateField(default="2999-12-12")
Another
class readstatus(models.Model):
reading_status = models.BooleanField(default=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
article = models.ForeignKey(Posts, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
My View:
class DailyReading(ListView):
template_name = 'reading.html'
context_object_name = "data"
paginate_by = 20
def get_queryset(self):
if self.kwargs['status'] == "read":
queryset = piaoyou.objects.filter(readstatus__reading_status=True,readstatus__user=self.request.user)
return queryset
else:
queryset= Posts.objects.filter(readstatus__reading_status=False,readstatus__user=self.request.user)
return queryset
My Template:
{% for info in data %}
<quoteblock>
<ul>
<li><a href="{{ info.get_absolute_url }}">{{ info.title }}
<footnote></footnote>
</a>{{ info.post_date }}</li>
<footnote>{{ info.get_abstract_content }}</footnote>
</ul>
</quoteblock>
{% endfor %}
OMG, I just figured out how to do this.
For an article that has been read by the requesting user, we can just pass queryset = Post.objects.filter(readstatus__reading_status=True, readstatus__user=self.request.user)
For an article that has not been read by the requesting user yet, we can pass Posts.objects.all() into the template.
Then in the template:
We need {% if instance.readstatus_set.all %} this line to make things work. Assume there is no data about whether this requesting user has read the article, the instance should not have readstatus_set.all, which means the user has not read the article yet. Once checking this if condition, we can carry out to check other conditions in the loop.
I've been advised that when it comes to updating a user I should use Django forms rather than rolling my own. As such, I've turned to Django forms but hit a bit of a wall.
A user in my system is defined, partly, as so:
#models.py
class Freelancer(AbstractBaseUser):
email = models.EmailField(primary_key=True)
first_name = models.CharField(max_length=128)
surname = models.CharField(max_length=128)
university = models.CharField(max_length=256)
verified = models.BooleanField(default=False)
biography = models.TextField(default="")
skills = models.ManyToManyField(Skill)
created_date = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
I have a URL:
#urls.py
url(r'^profile/$', views.Profile.as_view(), name="profile"),
And the view:
#views.py
class Profile(UpdateView):
model = Freelancer
fields = ['email']
template_name_suffix = '_update_form'
The problem is that I need to tell the server what Freelancer I want to update. I've tried adding (?P<pk>\d+)/ into the URL regex as I saw on a few tutorials but when I pass in the id of a Freelancer - as automatically created in the schema - it doesn't retrieve a Freelancer. Based on my model, what should I do?
I think it's a bad idea to use the email address as primary keys. What if a user changes their email address?
It might be a better idea to have unique=True for the email address, and let Django create the automatic primary key. Then including (?P<pk>\d+)/ in your url should work.
If you must use the email as the primary key, you need to change the regex from (?P<pk>\d+)/, which will only match digits, to something like
(?P<pk>[\w#.-]+)
The above might not catch all email addresses. I think Django contains a better character class, but I can't find it at the moment.
I think you are just doing it in a wrong way.
Here is what you need to do:
First of all I'd recommend you to add a pk to your model, as having email as a pk is a bad idea.
Create a url for update view
An example:
url(r'^profile/(?P<pk>[\d]+)/edit/$',
views.ProfileUpdateView.as_view(), name='edit_profile')
Create an UpdateView
An example:
class ProfileUpdateView(UpdateView):
model = Freelancer
fields = ['email']
template_name = "profiles/profile_edit.html"
Create a template for the form
An example:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
Now you need to add this link wherever you want:
Edit
When you vist the url you will go to update page.