How to use django-siteflags to bookmark site objects? - python

The package is here and here but I cannot get it to work.
Here is my models.py file
class Video(models.Model, ModelWithFlag):
name = models.CharField(max_length=255)
file = models.FileField(upload_to="static/videos/", null=True, verbose_name="", unique=True)
def __str__(self):
return self.name
And the views.py file
def user_bookmarked_video(request, bookmark_id):
video = get_object_or_404(Video, pk=bookmark_id)
# Now a user adds this article to his bookmarks.
video.set_flag(request.user)
How should the urls.py and .html look like ?

The most of the question is not related to siteflags itself.
See "Writing more views" to have an example of urls.py.
For example, it might look like
path('videos/<int:bookmark_id>/', views.user_bookmarked_video, name='videos_bookmarked'),
However your bookmark_id is missleading, since it's a video ID, not a bookmark ID. Moreover your view is named user_bookmarked_video(), but it's not what it does — it just sets a flag (bookmark) on some video object.
If you plan to use this view just to set a bookmark you'd better name it like set_video_bookmark() and redirect at the end of the function, instead of html rendering.
If your intention was to show all bookmarked videos for current user then there's no need to accept bookmark_id argument for your view and flagging on every view call.
Your html may look like as you want, depending on what do you want to see.
For example:
<h1>{{ video.name }}</h1>

Related

django URLs MultipleObjectsReturned error

I am making a simple webapp with Django. A user can have a profile, and under that profile create a blog post.
For example:
"path('profile/<int:pk>/',profile, name='profile')"
Returns the URL
"http://127.0.0.1:8000/profile/1/"
A user can then write blog posts which have the name in the URL
Example:
path('profile/<int:pk>/blog/<str:name>',Blogs, name='Blogs'),
Returns the URL
"http://127.0.0.1:8000/profile/1/blog/HelloWOrld"
However, IF two different users both name their blogs the same exact name, i get a 'MultipleObjectsReturned' Error.
I thought that by having the user PK earlier in the URL it would ensure that it would be unique, even if two blogs were called the exact same thing.
Views.py
def Blog(request, pk, name):
blog = Restaurant.objects.get(name=name)
user = CustomUser.objects.get(pk=pk)
if not user.id == request.user.pk:
raise PermissionDenied()
else:
context = {
'user': user,
'blog': blog,
}
return render(request, 'blog/blogs.html',context)
IS there any way to work around this without using the PK of the blog as well?
And if anyone could explain why my logic was wrong and it wasn't working in the first place.
Thanks.
You need to make sure you get the blog of that name of that user. I don't know exactly how your blog models look, but it's going to be something like
user = CustomUser.objects.get(pk=pk)
blog = Restaurant.objects.get(name=name, user=user)
And on the model, use the 'unique_together' property to ensure that the combination of user and blog name are unique, otherwise these URLs aren't going to work. Having the name completely unique as in George's answer isn't necessary and would mean that users couldn't create blog posts with titles already made by another user.
You need to make name field unique, and use SlugField for this if you want to use clean url:
class Restaurant(models.Model):
name = models.CharField(unique=True, ...)
slug = models.SlugField(unique=True, ...)
...

How to access object count in template using model manager?

I have a model which creates Memo objects. I would like to use a custom Model Manager's posted method to return the total number of Memo objects - then use this number within a template. I am trying to keep as much of my code as possible within my Models and Model Managers and less within my Views as I read that this was a best practice in 'Two Scoops of Django'.
In the shell I can get the number of memos as such:
>>> from memos.models import Memo
>>> Memo.objects.all()
<QuerySet [<Memo: Test Memo 2>, <Memo: Test Memo 1>]>
>>> Memo.objects.all().count()
2
This is what my Model and Model Manager look like:
class MemoManager(models.Manager):
use_for_related_fields = True
def posted(self):
return self.count()
class Memo(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_time = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
objects = MemoManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('memos-detail', kwargs={'pk': self.pk})
I know this is clearly the wrong way to do it but I have confused myself here. So how do I use my Model Manager to get the count of objects and use it in a template like: {{ objects.all.count }}?
P.S. I see other posts that show how to do this within the view but as stated I am trying not to use the view. Is using the view required? I also understand my posted method is written incorrectly.
I'm sorry but you have misinterpreted what was written in TSD. The Lean View Fat Model is meant to keep code which pertains to 'business logic' out of the views, and certain model specific things. A request should be handled by a view. So when you want to load a template, you must first have a GET request to your app.
A view function should be written such that Validation of POST data or the Creation of a new object in DB or Querying/Filtering for GET requests should be handled in the corresponding serializer/model/model manager.
What should be happening while you want to load your template.
Have a url for the template that you have created and a view function mapped for it
In the view function you should render said template and pass the necessary data inside the context.
To keep in line with the Lean View Fat Model style, if you want to get a Queryset of of Memo's but only those which have their is_deleted fields set to False, you can overwrite the model manager get_queryset() method for Memo model.
If you want to create a new Memo with a POST request, you can handle
the creation using a ModelForm!
Hope this clears things up!
EDIT:
How to pass a context to a template, in your case the memo count.
def random_memo_view(request):
context = {'memo_count': Memo.posted()}
return render(request, 'template.html', context=context)
RE-EDIT
I just checked that you were using DetailView. In this case follow this from the django docs.
Class Based Views: Adding Extra Context

How to make page content Dynamic with Flask?

I have a database which contains more than table one of them authors and their names, jobs, social accounts, etc.
I need to make a static page template and a route for that page so if anybody clicks on that author name in the site, take all of his information's from the database table and showing them on the page.
In a different way, i need to make a function to handle the request if anybody clicked on that author to now more about him, thus, i have a different request every time including a different author .
I can do that line by line for each on of them but it sounds bad, because i don't want to end up with 1000 lines of code, there is alot of them out there inside the table .
Please any way to do that in clear way, as always any help would be really appreciated :) .
For communication with the base use:
http://flask-sqlalchemy.pocoo.org/2.1/
for templete Jinja2
Declaring Models base
http://flask-sqlalchemy.pocoo.org/2.1/models/
Sample code
#app.route('/author/<username>')
def show_user(username):
user = User.query.filter_by(username=username).first_or_404()
name = user.name
last_name = user.last_name
adres = user.adres
return render_template('show_user.html', user=user, name=name, last_name=last_name, adres=adres)

Django: How to return all models associated with a ForeignKey including all attributes of those models?

I have an app that I want to simply display all the URL links a page has associated with it when that page is visited.
It's similar to reddit in that there are many userpages (aka subreddits) and each page has an infinite possible amount of submitted links associated with it. The newlinkposts records are associated with a certain page via a ForeignKey.
Given a page, wow can I get all the related newlinkpost objects (including their corresponding likes, link comment, and post date) returned, in order to display them in a template?
My newlinkpost object is defined as follows:
class newlinkpost(models.Model):
newlink_tag = models.ForeignKey('userpagename') #tags link to which userpage it belongs to
link_comment = models.CharField(max_length=128) #comment to go along with post
post_date = models.DateField(auto_now=True, auto_now_add=False, null=False) #submission datestamp. later make it track editable posts if edit function is implemented
url = models.URLField(max_length = 1024, null=False) #actual submitted link
link_likes = models.IntegerField(null=False, default=0) #need to later create like button which will +1 the value
def __unicode__(self):
return self.url
When you add a ForeignKey within a model, as well as creating an attribute in the source model (in your case, newlinkpost) allowing you to find the one associated object, Django also creates a corresponding attribute inside the target model (in your case apparently userpagename).
By default this attribute is named after the source table, so in your case it will be newlinkpost_set.
That allows you to ask the question you're looking to answer: which newlinkpost objects have this userpagename?:
all_links = userpagename_instance.newlinkpost_set.all()
If you wish to apply additional filters, you can use the filter method instead:
some_links = userpagename_instance.newlinkpost_set.filter(...)
The newlinkpost_set attribute contains a RelatedManager object, which is a subtype of Manager, allowing you to use the same set of methods you could use on newlinkpost.objects, along with some additional methods allowing you to create new related objects.
Here's an example view using this technique: (this assumes you've got the model classes imported into the views module):
from django.shortcuts import render
def user_page(request, user_id):
page = userpagename.get(pk=user_id)
links = page.newlinkpost_set.all()
return render(
request,
"myapp/user_page.html",
{
page: page,
links: links,
}
)
...and here's an example of using that "links" variable in the template:
<ul>
{% for link in links %}
<li><a href="{{ link.url }}">{{ link.link_comment }} - {{ link.link_likes }} likes</li>
{% endfor %}
</ul>
You just use the reverse relationship.
my_userpagename.newlinkpost_set.all()

How to pass values to defined template from views.py in Django-python

I have a model like this:
class EventTypeCategory(models.Model):
name = models.CharField(max_length=50, verbose_name="Name")
user = models.ForeignKey(User, verbose_name="User")
Message_slug = models.SlugField(blank=True, verbose_name="Message")
def __unicode__(self):
return self.name
In urls.py:
url(r'^categ/$',
'eventcateg_detail', name='eventcateg_detail'),
In views.py:
def eventcateg_detail(request,event_categ_id=None, event_categ_slug=None):
I want to add/edit/delete(CRUD) above defined value i.e name and Message_slug by template level. I am not getting any hint how to relate url.py with views.py and what should be definition of eventcateg_detail function.How this function will pass values to template (template name will be categ.html)
I am newbie in Django :)
want your help
You need to allow the URL to accept parameters to allow you specify which event category you want to view:
/categ/outdoor-events/
/categ/catered-events/
...
Do do this, you use a named URL pattern in your url scheme:
url(r'^categ/(?P<slug>[-\w]+)/$','eventcateg_detail', name='eventcateg_detail'),
and in your view:
from django.shortcuts import get_object_or_404, render
def eventcateg_detail(request,slug):
return render(request, "categ.html", {
'obj' : get_object_or_404(EventCateg, Message_slug =slug) # You should change Message_slug to just slug
})
and in your template:
<h1>{{ obj.name }}</h1>
So when a user enters a URL like we have outlined above, it gets matched to our URL pattern and the slug part of the url (catered-events) gets passed as a parameter to our view.
It's better that you follow the Django tutorial first, this is all covered in there. See for example part 3 of the tutorial for more information on how to relate urls.py with views.py and part 4 discusses passing variables to the template.
I believe that a view function is only passed an httprequest when it is called by the Django framework, the other two parameters of the function will only be useful if you call the function yourself but will not be useful through the web.
As pointed out in the comments I was mistaken in my belief, extra parameters can be passed as dynamic urls (i.e. urls designated like this url(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),. See this link and the answer by #pastylegs
The Django Admin will allow you to edit all model fields if this is what you are after. Instructions on setting it up can be found in the Django documentation.
However I think what you are asking is how to enable CRUD editing through the web to users who are not admin level users. In that case you have many options. One of those options is to use a pre-built framework for Django like piston. Another way would be to use generic views
The other option is to build views yourself enabling operations on your model. In that case all of Django is available to you. You can pass parameters to your custom functions within the httprequest, for example as POST data.

Categories

Resources