I have followed http://neutronx.github.io/django-markdownx/js/docs/markdownx.html#MarkdownX docs but can't get it done properly.
What is the correct way to setup two or more editors in the same page?
You don't have to set it up that way. MarkdownX is already initiated as your load {{form}} and {{form.media}}, so it has no meaning. Now, coming to your question. Using two editors on the same page in really straight forward.
in your forms.py:
from django import forms
from markdownx.fields import MarkdownxFormField
class FirstForm(forms.Form):
yourfirstfield = MarkdownxFormField()
class SecondForm(forms.Form):
yoursecondfield = MarkdownxFormField()
in your views.py:
from django.shortcuts import render
from .forms import FirstForm, SecondForm
def form_view(request):
context = {
'first_form': FirstForm,
'second_form': SecondForm
}
return render(request, 'form_template.html', context)
in your form_template.html:
<form>
<p>{{first_form}}</p>
<p>{{second_form}}</p>
</form>
I hope that helps!
Related
The application I inherited was at Django 2.2. I have gradually updated to 4.1 and everything works except the Django Autocomplete Light fields. For some forms.ModelForm, I have a box with a correct list that can be selected but it does not have the ability to type the first few letters and select from that filtered list. Most of the autocomplete fields are on forms.Form and either display a dropdown box where the only choice is '-----', a scroll bar only with no list, or a box that is 2 x 47 pixels.
I have gone through the DAL documentation but could not find a solution. I have searched here plus other Google searches but I have not found a solution.
I do realize that parts of the code use the older URL pattern that includes ^, $, and ?P< items. I have tried to change these for one of the apps but it did not solve the issue.
forms.py
# Forms
from django import forms
from django.forms import ModelForm
# Models
from login.models import User
from .models import Suggestion, SuggestionDecision, Implementation
# Autocomplete
from dal import autocomplete
class ReviewForm(forms.ModelForm):
class Meta:
model = Suggestion
fields = ['suggestion', 'supervisors', 'managers']
widgets = {
'supervisors': autocomplete.ModelSelect2Multiple(url='login:user_autocomplete'),
'managers': autocomplete.ModelSelect2Multiple(url='login:user_autocomplete')
}
urls.py
from django.urls import path, re_path
from process_improvement import views as pi_views
app_name='process_improvement'
re_path(r'^autocomplete/suggestion/$', pi_views.SuggestionAutocomplete.as_view(), name='suggestion_autocomplete')
views.py
from dal import autocomplete
from django.urls import reverse
from django.shortcuts import redirect
from django.contrib.auth.mixins import LoginRequiredMixin
class SuggestionAutocomplete(autocomplete.Select2QuerySetView, LoginRequiredMixin):
def get_queryset(self):
qs = Suggestion.objects.all()
if self.q:
for term in self.q.split():
qs = qs.filter(Q(suggestion__icontains=term) | Q(pk__icontains=term) | Q(created_at__icontains=term))
return qs
suggestion.html
<form method="POST" class="needs-validation" id="suggestionForm" data-parsley-validate>
{% csrf_token %}
<label for="id_supervisors">Supervisors*</label>
{{ suggestionForm.supervisors }}
{{ suggestionForm.suggestion | as_crispy_field }}
</form>
This is the code for the fields that appear with a list that can be selected but not the option to enter the first few letters of the name. What do I need to change to get this working properly?
This is a basic question but I can't figure out what I'm doing wrong...
I'm trying to render a detail view in my django site, but my calls to get the object are just failing or else not rendering.
Here is what I have:
views.py
from django.template import loader
from django.views.generic.base import TemplateView
from django.http import HttpResponse
from .models import user_profile
def detail(request, content_id):
template = loader.get_template('profiles/detail.html')
profile = user_profile.objects.get(pk=content_id)
context = {'profile': profile}
return HttpResponse(template.render(context, request))
Within the template, I have simply been testing the calls using:
<h1>{{ profile }}</h1>
<h1>{{ profile.name }}</h1>
This is my first time rendering this from scratch, I know I'm missing something dumb I just can't sort it. Thank you!
edit This current setup receives a 500 error. Without the get(pk) statement it loads, but doesn't show the variables, just the rest of my HTML.
upon request, here is the urls.py:
urlpatterns=[
path('<int:content_id>/', views.detail, name='detail'),
]
edit: solution Solved! Ends up there was an issue with the model where a migration was not properly performed and a column was read as missing.
Model was contained a column that was missing in the database. Even though it was not being called, it still resulted in an error when the model was referenced.
I'm trying to display text in a HTML page which i'm saving in django admin interface and whenever i save the data and trying to display the text in html page instead of the text a line space was being printed.
Output attaching the code screenshots here views file, HTML
page, Models, Django Admin Interface
views.py
from django.shortcuts import render
from .models import todolist
def index(request):
todo=todolist.objects.order_by('id')
context={'todo': todo}
return render(request,'todotemplates/index.html',context)
models.py
from django.db import models
# Create your models here.
class todolist(models.Model):
text=models.CharField(max_length=50)
complete=models.BooleanField(default=False)
def __str__(self):
return self.text
In your html use need to use i inside loop not todo:
{% for i in todo %}
<li class='whatever'>{{ i.text }}</li> <!-- use i.text -->
{% endfor %}
Please change your view code to below:
def index(request):
todohtml = ""
defectsobj1 = PrdDefect.objects.all()
for eltdefect1 in defectsobj1:
todohtml = "<li>"+eltdefect1.text+"</li>"
return render(request, "page.html", {"todohtml":todohtml})
Also can you check you database if you model is saving entries properly in db
I'm trying to get the standard Aldryn Newsblog Buttons working in my Frontend Page. So every User can Add, Delete and Edit Articles(only the articles they created themselves but thats not the question). This is the Menu with the links:
Menu in the Toolbar
So i want to add a Button in my template wich triggers the edit, add or delete prompt: Delete prompt
I hope someone can help me. Thanks in advance.
If you really don't want all employees to see the toolbars, then you're taking on quite a bit of extra work. I would still consider this as an option, as you can apply permissions so that a user can only edit the content you allow, which means that users can take full advantage of Django CMS's built in functionality, which is great.
If you still don't want to take this route then you're going to have to build your own mini admin for your article model. Below I've quickly thrown together an idea for how you can approach this to hopefully help point you in the right direction.
First, your article view should be something like:
from django.views.generic import DetailView
from .models import Article
class ArticleView(DetailView):
context_object_name = 'article'
model = Article
template_name = 'path/to/article.html'
def get_context_data(self, **kwargs):
context = super(ArticleView, self).get_context_data(**kwargs)
context['show_controls'] = (self.request.user.is_authenticated() and
context[self.context_object_name].article == self.request.user)
return context
With the article template like:
<section>
{% if show_controls %}
<div class="controls">
Delete
Edit
</div>
{% endif %}
<article>
...
</article>
</section>
The path to delete view could be a confirm page like the Django admin. So you'd have a view like:
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect, render
from .models import Article
#login_required
def delete_article(request, article_pk):
if request.method == "POST":
article = get_object_or_404(Article, pk=article_pk)
if request.user != article.author:
raise PermissionDenied
article.delete()
return redirect('/redirect/url')
else:
context = {}
...
return render(request, 'path/to/confirm/delete.html', context)
With a template along the lines of:
<section>
<form method="POST">
{% csrf_token %}
<p>Are you sure you want to delete?</p>
<input type="submit" value="Delete">
</form>
</section>
You'd then create a similar setup for the edit page, navigate the user to a page that has a form where the fields can be amended and submitted etc.
I'm using Django CMS with Django Parler and have run into a problem that is driving me mad, so if anybody could help, it would be much appreciated!
So I'm creating a simple blog app that has the slug as a translatable field. Here is the model simplified:
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
translations = TranslatedFields(
...
slug = models.SlugField(_('slug'), max_length=255, blank=True, allow_unicode=True),
meta = {'unique_together': (('language_code', 'slug'),)}
)
...
def get_absolute_url(self):
return reverse('blog:article_detail', kwargs={'slug': self.slug})
Here are the urls:
from django.conf.urls import include, url
from .views import ArticleDetailView
urlpatterns = [
...
url(r'^(?P<slug>\w[-\w]*)/$', ArticleDetailView.as_view(), name='article_detail'),
]
And finally here is the view:
from django.views.generic import DetailView
from parler.views import TranslatableSlugMixin
from .models import Article
class ArticleDetailView(TranslatableSlugMixin, DetailView):
model = Article
template_name = 'blog/_article.html'
I've created an article that is in English, French & German, with a different slug for each language, lets call those:
/en/blog/english-slug
/fr/blog/french-slug
/de/blog/german-slug
I can navigate to these all correctly, but in Django CMS you have the language menu at the top that on the English page shows the links as:
/en/blog/english-slug
/fr/blog/english-slug
/de/blog/english-slug
This is fine, as that's what the TranslatableSlugMixin in the view handles (see here http://django-parler.readthedocs.io/en/latest/api/parler.views.html).
So when I click one of the links (say the French one) the view correctly finds the correct article and redirects me to the correct url. So clicking:
/fr/blog/english-slug
Has taken me correctly to:
/fr/blog/french-slug
But here's where it's all going wrong. I now want to navigate back to the English page, which is showing as:
/en/blog/french-slug
But when I click the link it navigates to a 404. This is the same if I navigate to the German URL from the French one. However if I go from English to German straight away it works.
Sorry, I know this is confusing to explain but it seems the translation works one way from base/default to other language but doesn't work correctly when swapping between languages or back to the base/default.
Surely TranslatableSlugMixin is designed to allow this to happen?! So am I missing something here?
Any help would be much appreciated. Happy to provide more info if necessary.
Thanks
Ok so I've figured out how to make this work and it turns out it's a combination of things...
Using the default Django CMS chooser was a mistake:
{% language_chooser "menu/language_chooser.html" %}
This leads to the URLs I described above:
/en/blog/english-slug
/fr/blog/english-slug
/de/blog/english-slug
Reading the Django Parler docs led me to using their language navigation menu:
{% for lang_code, title in LANGUAGES %}
{% get_language_info for lang_code as lang %}
{% get_translated_url lang_code as tr_url %}
{% if tr_url %}<li{% if lang_code == LANGUAGE_CODE %} class="is-selected"{% endif %}>{{ lang.name_local|capfirst }}</li>{% endif %}
{% endfor %}
This leads to the urls pointing to the correct location:
/en/blog/english-slug
/fr/blog/french-slug
/de/blog/german-slug
For the Django Parler navigation to work I needed to update the get_absolute_url() in the model to handle different languages. I did that as follows:
from django.utils.translation import get_language
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
def get_absolute_url(self):
language = get_language()
if self.has_translation(language):
slug = self.safe_translation_getter('slug', language_code=language)
return reverse('blog:article_detail', kwargs={'slug': slug})
# no translation so fallback to all article list
return reverse('blog:article_list')
Phew! That was a headache! Hopefully this helps somebody else in the future!
P.S. During my research I came across this blog app that seems really great:
https://github.com/nephila/djangocms-blog
It helped me get to the bottom of this nightmare!
UPDATE
Looking at the get_absolute_url() in djangocms-blog (link above), they have a far better solution to the problem. Their implementation is:
from django.utils.translation import get_language
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
def get_absolute_url(self, lang=None):
if not lang or lang not in self.get_available_languages():
lang = self.get_current_language()
if not lang or lang not in self.get_available_languages():
lang = get_language()
with switch_language(self, lang):
slug = self.safe_translation_getter('slug', language_code=lang, any_language=True)
return reverse('blog:article_detail', kwargs={'slug': slug})
Thanks nephila, this has saved me from a lot of cursing and frustration :)