I've followed the documentation on how to customize models. I want to add an extra url field to the gallery, so I've added this.
extra_url = models.URLField(max_length=200, blank=True, null=True)
Everything shows up fine in the Django admin, but I have no idea how to call up that field in the actual HTML.
The documentation says:
The above code is enough to start entering tags in the admin interface. To use/display them in the front end, you will also need to override Photologue’s own templates - as the templates are likely to be heavily customised for your specific project, an example is not included here.
I have already overridden the Photologue's templates with my own. I'm too much of a novice to figure it out without an example. I've just been guessing with no luck.
<div class="row col-lg-12">
<div class="col-xs-6 col-md-8">
<h1 class="page-header">{{ gallery.title }} </h1>
<a href="{% however you call up the extra_url field %}">
<p class="muted"><small> {{gallery.date_added }}</small></p>
{% for photo in gallery.public %}
<div class="col-xs-6 col-xs-3">
<a href="{{ photo.get_absolute_url }}">
<img src="{{ photo.get_thumbnail_url }}" class="thumbnail" alt="{{ photo.title }}">
</a>
</div>
{% endfor %}
<div>{% trans "View all galleries" %}</div>
</div>
</div>
Are you creating an extra model exactly as per the documentation, i.e.:
class GalleryExtended(models.Model):
# Link back to Photologue's Gallery model.
gallery = models.OneToOneField(Gallery, related_name='extended')
# Now your extra field.
extra_url = models.URLField(max_length=200, blank=True, null=True)
If yes - then within your template you can write {{ gallery.extended.extra_url }} to display that new field.
The key is the related_name, which tells Django how to access the new new model from the existing Gallery - and you already have the Photologue Gallery in your template, as variable {{ gallery }}.
Related
How do I edit this code to count the times the "Link" was clicked and add this to the database model "T_shirt" in a new column?
HTML
<ul class="products">
{% for v in owner_obj %}
<div class="container">
<a href={{ v.Link }} target="_blank" rel="noopener noreferrer">
<img src={{ v.Images }} width="150" height="150">
</a>
<figcaption> {{ v.Titles }} </figcaption>
<figcaption> <b>{{ v.Prices }} </b></figcaption>
</div>
{% endfor %}
</ul>
Models.py
class T_shirt(models.Model):
Images = models.ImageField()
Titles = models.CharField(max_length=250, primary_key=True)
Prices = models.CharField(max_length=250)
Link = models.CharField(max_length=250)
You can make a model thats called clickcounter. Give it two fields 1. url(charfield) 2. counter (IntegerField).
Make a function with 1 parameter for url. exampfunc(url).
In that function check if the url already exist and update the counter with +1 otherwise create a new object.
You would define this function in every view you would like to count the urls of. This is one way, there always are better ways. But you need to start somewhere right ?
I'd like to put like and comment section in my blog project with some info like no. of likes and comments and also show user who comment on it in django project but don't know how.
its a simple blog so i just want a like button and a comment button, above that its need to show how much likes and comment that post have and at least need to show one comment below that just like a normal blog have
her is my html code:
{% for post in post %}
<article class="media mt-4">
<div class="media-body">
<img class="rounded-circle article-img" id="dp" src="{{ post.author.profile.image.url }}">
<div class="article-metadata">
<a class="mr-2" href="{% url 'Love Travel-User' post.author.username %}">{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted|date:"F d, Y" }}</small>
</div>
<h2><a class="article-title" href="{% url 'User-Posts-Details' post.id %}">{{ post.title }}</a></h2>
<img src="{{ post.img.url }}" class="article-img">
<p class="article-content">{{ post.content }}</p>
</div>
</article>
{% endfor %}
views.py
class PostListViews(ListView):
model = Post
template_name = 'userpost/posts.html'
context_object_name = 'post'
ordering = ['-date_posted']
paginate_by = 7
models.py
class Post(models.Model):
title= models.CharField(max_length=100)
img = models.ImageField(upload_to='pics')
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author= models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('User-Posts-Details', kwargs={'pk': self.pk})
any help is appreciated
I will not give the code but I will explain how to do it.
I will help you with the comments part.
You have to create a model Comment link with a Foreign key to Post model. This will allow you to create Comment objects, then you will be able to stock them in your database and display them.
For the view, I prefer Function Based View, it will be easier for you.
And you have to create a ModelForm. To simplify creation of comments you should create an other html page.
I hope it was clear,
Do not hesitate if you have any questions !
I would like to be able to use my external app data on django cms page.
I am able to use custom plugin data but not data from normal django app
I tried creating views to handle my data but how do I call this view from django cms pages?
here is exactly what I am asking for but his explanation is shallow and the link provided in the answer is no longer in use.
Here is my model:
class ExternalArticle(models.Model):
url = models.URLField()
source = models.CharField(
max_length=100,
help_text="Please supply the source of the article",
verbose_name="source of the article",
)
title = models.CharField(
max_length=250,
help_text="Please supply the title of the article",
verbose_name="title of the article",
)
class Meta:
ordering = ["-original_publication_date"]
def __str__(self):
return u"%s:%s" % (self.source[0:60], self.title[0:60])
My template has placeholders
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
<section class="section">
<div class="container">
<div class="row">
<!-- header-->
<div class="col-lg-12">
<div class="updates">
{% placeholder "header" %}
</div>
</div>
<!-- header end-->
</div> <!-- end row -->
but I don't mind displaying this data anywhere on the template if not possible inside a place holder
I have a custom page that I am using in Django cms.
I would like to display the above data is a section in the Django cms page
If this model was inheriting from CMSPlugin then that would be easy because I could use a custom plugin in my placeholder
I expect to display the data from my model in the template.
I was able to achieve this by doing the following:
#plugin_pool.register_plugin
class ArticlesPluginPublisher(CMSPluginBase):
model = ArticlesPluginModel
name = _("Articles")
render_template = "article_plugin/articles.html"
cache = False
def render(self, context, instance, placeholder):
context = super(ArticlesPluginPublisher, self).render(
context, instance, placeholder
)
context.update(
{
"articles": Article.objects.order_by(
"-original_publication_date"
)
}
)
return context
The plugin model(ArticlesPluginModel) is just for storing the configurations for the instance of the plugin. Not the actual articles.
Then the render will just add to the context the relevant articles from the external app(Article)
You must somehow connect the ExternalArticle with a page object. For example
by defining the ExternalArticle as a page extension
or with an AppHook
or - low-tech - with a PageField on the ExternalArticle model
{% load cms_tags %}
<h1>{{ instance.poll.question }}</h1>
<form action="{% url polls.views.vote poll.id %}" method="post"> {% csrf_token %}
{% for choice in instance.poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
I tried to show similar posts to an article in an aside column. A feauture sites like youtube and even stack overflow. Not having anyone to ask about it, I assumed articles listed on the side were ones with similar tags. But it's not working its saying nothing matches. this is what I had in my post_detail.html:
{% block content %}
<div class="row" style="margin-top: 70px">
<div class="col-sm-8">
{% if instance.image %}
<img src='{{ instance.image.url }}' class="img-responsive" />
{% endif %}
<p>Share on:
<a href="https://www.facebook.com/sharer/sharer.php?u={{ request.build_absolute_uri }}">
Facebook
</a>
<a href="https://twitter.com/home?status={{ instance.content | truncatechars:80 | urlify }}%20{{ request.build_absolute_uri }}">
Twitter
</a>
<a href='https://plus.google.com/share?url={{ request.build_absolute_uri }}'></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url={{ request.build_absolute_uri }}&title={{
instance.title }}&summary={{ share_string }}&source={{ request.build_absolute_uri }}">
Linkedin
</a>
</p>
<h1>{{ title }}<small>{% if instance.draft %}<span style="color:red"> Draft</span>{% endif %} {{instance.publish}}</small></h1>
{% if instance.user.get_full_name %}
<p>By {{ instance.user.get_full_name }}</p>
{% else %}
<p>Author {{ instance.user }}</p>
{% endif %}
<p><a href='{% url "posts:list" %}'>Back</a></p>
<p><a href='{% url "posts:delete" instance.id %}'>delete</a></p>
<p>{{instance.content | linebreaks }}</p>
<hr>
</div>
<div class="panel panel-default pull-right" style="height: 1000px">
<div class="panel-heading">
<h3 class="panel-title">Similar Articles</h3>
</div>
==========right here====================
<div class="panel-body">
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
</div>
==========right here====================
</div>
</div>
{% endblock content %}
and this is my view
def post_detail(request, slug=None):
instance = get_object_or_404(Post, slug=slug)
if instance.publish > timezone.now().date() or instance.draft:
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
share_string = quote_plus(instance.content)
context = {
"title": "detail",
"instance": instance,
"share_string": share_string,
}
return render(request, "posts/post_detail.html", context)
if this approach is beyond syntax correction and needs to be rewritten. I don't mind writing it over the correct way. This is my second month working with Django. To me this way made sense but it's not working. And are sites like youtube which has a video and similar videos to the right of the main video, are those videos there because they share similar tags? any and all help is welcome.
In the long run and to not reinvent the wheel using a reusable Django application already tried and tested is the sensible approach. In your case there is such app: django-taggit
and is easy to use:
You install it
pip install django-taggit
Add it to your installed apps:
INSTALLED_APPS = [
...
'taggit',
]
Add its custom manager to the model on which you want tags
from django.db import models
from taggit.managers import TaggableManager
class YourModel(models.Model):
# ... fields here
tags = TaggableManager()
and you can use it in your views:
all_tabs = instance.tags.all()
It even has a similar_objects() method which:
Returns a list (not a lazy QuerySet) of other objects tagged similarly
to this one, ordered with most similar first.
EDIT
To retrieve similar posts you should use:
similar_posts = instance.tags.similar_objects()
and to get only the first, let's say, 5 similar posts:
similar_posts = instance.tags.similar_objects()[:5]
where instance is a instance of the Post model.
you should let us know what is not matching.
your post_detail tries to find a Post with a tag's slug.
instance = get_object_or_404(Post, slug=slug)
I doubt that's what you intended.
get_object_or_404 either tries to find an exact match or raise error.
Since your original post has the tag, you will be getting the same post or multiple.
The following block of code is not what you said you wanted either.
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
It lists all tags of the original post, doesn't list related post (via tag)
If you want to show related post, and you intent to use tag to define relatedness, define a method in your post model to return such related posts.
def get_related_posts_by_tags(self):
return Post.objects.filter(tags__in=self.tags.all())
are those videos there because they share similar tags?
Not sure how they judge the relatedness, you should ask that in a separate question.
If I have to guess, it would be more than just tag comparison though.
** edit
Actually, proper term for relatedness is similarity.
You might find further info by googling document similarity.
{% for post in instance.get_related_post_by_tag %}
// href to post.absolute_url
{% endfor %}
SOLVED by Peter DeGlopper:
Thank you for your help it solved my issues, I really do appreciate it. I was banging my head against the table.
I didn't have to change my ModelForm. Looking at the HTML source I noticed in the input tag checked="checked" A subnet was being outputted as checked but it wasn't showing checked in my browser. This was in Firefox 24.2.0 in CentOS (On a VM), so I went to my Windows 7 host and loaded up Firefox 26.0 it worked, and worked fine in IE8 as well. That was weird, but it explains your confusion of that it should just work.
For saving the fields thanks to you I now see how I was over thinking it. And I am able to update the M2M field. I updated the TagUpdateView below to show the working code.
I have 2 issues with trying use an UpdateView with a M2M field...
The currently "tagged" subnets dont show up as checked in my template
How would I handle updating the M2M relationship in my TagUpdateView by overriding form_valid?
Any insight would be greatly appreciated.
Thanks.
Tag m2m models.py:
class Tag(models.Model):
tag = models.CharField(max_length=120)
group = models.ForeignKey(Group)
description = models.TextField(max_length=500)
subnet = models.ManyToManyField(Subnet, null=True, blank=True)
date_created = models.DateTimeField()
created_by = models.ForeignKey(User, related_name='tag_created_by')
date_modified = models.DateTimeField(auto_now=True)
modified_by = models.ForeignKey(User, related_name='tag_modified_by')
def __unicode__(self):
return self.tag
Tag ModelForm:
class TagForm(forms.ModelForm):
subnet = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), required=True, queryset=Subnet.objects.all())
class Meta:
model = Tag
exclude = ('date_created', 'created_by', 'date_modified', 'modified_by')
Tag views.py:
class TagUpdateView(UpdateView):
template_name = 'tag_update.html'
model = Tag
form_class = TagForm
def form_valid(self, form):
update_tag = form.save(commit=False)
update_tag.modified_by = self.request.user
update_tag.save()
form.save_m2m()
return super(TagUpdateView, self).form_valid(form)
My template "tag_update.html":
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block title %}Tag {{ object.tag }} Update{% endblock %}
{% block content %}
<h1>Tag {{ object.tag }} Update</h1>
<br />
<form action="" method="post" role="form">{% csrf_token %}
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label for="id_tag">Tag Name</label>
{% render_field form.tag placeholder=form.tag.label class="form-control" %}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-2">
<div class="form-group">
<label for="id_group">Group</label>
{% render_field form.group placeholder=form.group.label class="form-control"%}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="id_description">Description</label>
{% render_field form.description placeholder=form.description.label class="form-control" rows="5" %}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="id_checkbox">Link to Subnets</label>
{{ form.subnet }}
</div>
</div>
</div>
<br />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br />
{% endblock %}
You're overthinking it. Handling this kind of relationship can be a little bit complicated if you need to track information on the relationship model itself (like a modified timestamp for when a particular subnet/tag pair was created) but for the model relationships you've shown here, form.save_m2m() is sufficient - it handles the m2m relationship for you.
You wouldn't even need that if you didn't need to use commit=False on your initial form save so you can set your modified_by field.
For prepopulation - mostly this looks to me like it should follow the normal behavior and prepopulate. I would probably just use the widget class rather than explicitly instantiating it (widget=forms.CheckboxSelectMultiple rather than widget=forms.CheckboxSelectMultiple()) but I don't see why that would affect it.
For both problems, you might have good results by starting with a simple ModelForm with no customizations on subnet, just exclude set. Once that's working, put in the special view code to handle modified_by. Once that's working, change to a custom widget declaration for subnet - maybe initially using the meta widgets override dictionary rather than a custom field declaration for the first pass.