I am new to django and I have I think a pretty fundamental question.
Lets say I have this theme:
I made a project already, so I know a bit about know how to build models for dynamic content, pass them to views and admin panel etc, but:
Question: on the image above I marked 3 containers that include text. There is only one instance of this text on the whole website, and it's not repeatable. If I developed for myself I would just hard-code that, but what if I develop for a client, who needs to be able to edit those fields using the admin panel?
Am I supposed to create a separate class containing multiple (lets say 20) fields for these kind of containers for the whole website, pass that class in a view (and filter with [:1]) to use it in a template?
Thats the only thing I came up with. Although it would work I think it's a terrible solution.
What I would do is write a model that contains a TextField for the blurb to insert and a CharField to identify it, and a custom template tag that reads the blurb from the database by the argument you pass to it.
class Blurb(models.Model):
ident = models.CharField(..., db_index=True)
blurb = models.TextField(...)
PK ident text
1 main Hey! Do you like this template? This...
{% load blurb %}
...
{% blurb main %}
you could have 1 model with a selection field containing a descriptor for the text in the model.
Something like:
class SomeText(models.Model):
position = models.CharField(max_length=120, choices=POSITION_DESCRIPTORS)
text = models.TextField()
Related
I am studying Python and Django, my final goal is to create an administration panel that manages 2 things:
"dynamic article / item" (which can create types of forms to enter).
"dynamic taxonomies / tags" (which can create categories or groupers of the data "of the form type").
I have seen the documentation of DjangoCMS but I cannot find the names of these concepts, could you guide me?
thank you
You can do pretty much whatever you want to do. If you want to add to what a page gives you, extend the page;
http://docs.django-cms.org/en/latest/how_to/extending_page_title.html
I've used this to add images to pages, so you could use it to add tags or anything else you'd like.
Here's an example of attributing a colour to pages;
class PageColourExtension(PageExtension):
"""
Extend the page model with a background image field.
"""
page_colour = models.CharField(
_("Base colour"),
max_length=50,
null=True,
choices=COLOUR_CHOICES,
)
def __unicode__(self):
"""
Identify by the page it is tied to.
#return: page name
#rtype: str
"""
return '%s' % self.extended_object
extension_pool.register(PageColourExtension)
I'm not sure if djanog-cms is the right tool for your task. It's main purpose is to manage hierarchical pages, and the content on these pages. You need to keep in mind that this concept is already there, and cannot be changed, only extended.
For your specific case, I would recommend to create an own Article model, and then use the PlaceholderField, on your article model - it allows really dynamic content to be created, in the same fashion as when used on cms pages. See django-cms placeholder outside the cms docs for how to do that.
If you want to use django-cms and your custom application/article app alongside, you can use an app-hook to embed your urls under a cms page. See docs djanog-cms apphooks
I have a class property that vomits some HTML:
class Task (models.Model):
def test(self):
return """<img border="0" alt="" src="/%s/%s/%s" />""" % (UPLOADS_DIR, GRAPH_DIR, "task.svg")
test.allow_tags = True
How can I easily feed the returned HTML into the model’s admin page? It works for list_display() page. I tried to make a custom widget for the test() for its model page but my widget has failed to actually display the image. I don't want to solve this problem by making a custom template for this model. Basically I'm looking for a custom form or widget that just puts any HTML that test spits out into model's admin page without modifying the output of the property.
Any thoughts?
Thanks a lot!
Eras
I know you're not keen but I think overriding the template is going to be the best way to go.
A widget is associated with a particular field but your test() method isn't. And again django forms are just concerned with fields - they're about sending data back to the server - not presenting data - that's views and templates.
It shouldn't be too messy doing this by overriding a template. If you want it really clean, you could simply extend the existing template and then add your field at the bottom. Have a look at the docs on overriding admin templates. It's quite simple to override a specific template for a specific model.
Following up with the posting regarding reversed many-to-many look ups, I was wondering what the best practice for my project/picture problem is:
I want to register a number of projects and the users can upload (but not required) multiple project pictures.
Therefore I defined the following two classes:
from easy_thumbnails.fields import ThumbnailerImageField
class Project(models.Model):
name = models.CharField(_('Title'), max_length=100,)
user = models.ForeignKey(User, verbose_name=_('user'),)
...
class ProjectPicture(models.Model):
project = models.ForeignKey('Project')
picture = ThumbnailerImageField(_('Image'),
upload_to='user/project_pictures/', null=True, blank=True,)
def __unicode__(self):
return u'%s\'s pictures' % (self.project.name)
So for every user, I am displaying their projects in a "dashboard" via
projects = Project.objects.filter(user = logged_user)
which returns a list of projects with the names, etc.
Now I would like to display a picture of the project in the dashboard table. Therefore I have two questions I am seeking advice for:
1) Is the class setup actually the best way to do it? I split up the classes like shown above to allow the users to upload more than one picture per project. Would there be a better way of doing it?
2) How can I display the first picture of a project in the template, if a picture is available? Do I need to make a query on every ProjectPicture object which corresponds to a Project? Or is there an elegant Django solution for that problem?
It's not many-to-many relation, you use foreign keys. It's normal setup. To access first picture in template you can use {{ project.projectpicture_set.all.0 }}, it will generate additional query. To avoid it use prefetch_related.
I am a current web2py user, but find I still go back to Django once in a while (where I started). Specifically when working on projects where I want to make use of some specific django apps/plugins/extensions that don't yet exist in web2py.
One thing that I can't live without in web2py, which I am looking for a solution for in Django, is the way to create html forms from a db table and being able to then customize their look and layout in the view, without javascript.
Key things I am looking for:
Generate html form from a db table
Assign custom css classes/ids to each field in the generated html form (js disabled)
Place each form field/element in a pre-made html view via a method call in the view
i.e.
I have a table A. In web2py I can do (in controller):
def display_form():
form = SQLFORM(db.table_A)
#Can I do the following in Django? Assign custom CSS to each form field?
form.element(_name='email')['_class'] = = "custom_css_classes, list"
if form.accepts(request.vars, session):
response.flash = 'form accepted'
elif form.errors:
response.flash = 'form has errors'
else:
response.flash = 'please fill out the form'
return dict(form=form)
Then, in the View I can do:
form.custom.start
form.custom.widget.name
form.custom.widget.email
form.custom.widget.form_field_name
...
<div class="span-5 last"><input type="submit" class="register_btn" value="Sign Up"></input></div>
form.custom.end
The above takes a DB table, creates an HTML form, and then lets me stick each separate form field in any place in the pre-made HTML that I want (using those "custom" method calls on the passed "form" object. Including the custom css classes I assigned to each separate field of the generated html form.
See documentation for details on the above code:
http://web2py.com/book/default/chapter/06?search=define_table
http://web2py.com/book/default/chapter/07?search=sqlform#SQLFORM
http://web2py.com/book/default/chapter/05?search=#Server-side-DOM-and-Parsing
http://web2py.com/book/default/chapter/07?search=form.custom
How do I do the above in Django without dirtying my javascript with layout hacks. Assume javascript is disabled in the browsers where I need my app to run. Furthermore, I would love to make use of Django admin. Pylons solutions also welcome!
Links to articles/tutorials/howtos for this would be greatly appreciated.
Also, please make an equivalent result of the above code using the method you mention in your response...
Use ModelForm and override any field you wanna customize by explicitly declaring them.
If you want to set field attributes like class and id, you need to do something like this:
name = forms.CharField(
widget=forms.TextInput(attrs={'class':'special'}))
In case you are interested, you may change the order of the fields by specifying a fields sequence in your Meta class:
class Meta:
model = YourModel
fields = ('title', 'content')
You may read the full documentation here:
http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs
If you haven't already, take a look at Django's ModelForm. I am assuming that you have models mapped to the tables in question. Vanilla ModelForm instances will work without JS. However ModelForms are usually defined ahead of time and not constructed on the fly. I suppose they can be created on the fly but that would be a bit tricky.
Hey, i am currently working on a django app for my studies, and came to the point of l18n. Localizing the site itself was very easy, but now i have to allow users, to translate the dynamic content of the application.
Users can save "products" in the database and give them names and descriptions, but since the whole site should be localized, i must provide a way of translating theses names and descriptions to the users.
Is there a natural way in django to do this? Or do i have to realize it as part of the application (by representing the translations in the datamodel)
Thanks, Janosch
I would suggest checking out django-multilingual. It is a third party app that lets you define translation fields on your models.
Of course, you still have to type in the actual translations, but they are stored transparently in the database (as opposed to in static PO files), which is what I believe you are asking about.
There are two projects of note for translatable content in Django:
http://code.google.com/p/django-multilingual/
http://code.google.com/p/transdb/
I use django-multilingual for localize content and django-localeurl for choosing language based on url (for example mypage/en/).
You can see how multilingua and localeurl work on JewishKrakow.net page.
"i must provide a way of translating theses names and descriptions to the users."
"Is there a natural way in django to do this?"
Are you asking if Django can translate from language to language? Are you asking about something like http://translate.google.com/ ?
I don't think Django can translate user input into another language.
If you are going to do the translation for your users, this must be part of your data model.
Django's i18n filter allows you to have a table of translation strings. The documentation says this.
Embed translation strings in your Python code and templates.
Get translations for those strings, in whichever languages you want to support. This is something you do manually, by hiring translators or knowing a lot of languages yourself.
Activate the locale middleware in your Django settings.
I have 2 languages on my site: English and Arabic
Users can switch between languages clicking on a flag.
In models i use a proxy model:
class Product(models.Model):
name=models.CharField(max_length=100)
name_ar=models.CharField(max_length=100, default='')
def __unicode__(self):
return self.name
class Product_ar(Product):
def __unicode__(self):
return self.name_ar
class Meta:
proxy=True
In forms I use 2 forms instead of one:
class CollectionEditForm_en(forms.Form):
name = forms.CharField(label=_('Name'), max_length=100, widget=forms.TextInput(attrs={'size':'50'}))
product = forms.ModelChoiceField(label=_('product'), queryset=Product.objects.filter(enabled=True), empty_label=None)
class CollectionEditForm_ar(forms.Form):
name = forms.CharField(label=_('Name'), max_length=100, widget=forms.TextInput(attrs={'size':'50'}))
product = forms.ModelChoiceField(label=_('product'), queryset=Product_ar.objects.filter(enabled=True), empty_label=None)
In code check language this way:
if request.LANGUAGE_CODE=='ar':
CollectionEditForm=CollectionEditForm_ar
else:
CollectionEditForm=CollectionEditForm_en
So in templates i check:
{% if LANGUAGE_CODE == "ar" %}
{{product.name_ar}}
{% else %}
{{product.name}}
{% endif %}
Hope this solution will help somebody
It depends on who will provide the translations. If you want to provide a web interface to translation, then you need to develop that yourself, and also represent the translations in the database.
If the same translators who translated the site will also translate the data, you can provide them with the same model that they use for the site (presumably gettext), and you can then also use gettext for this content.
Also looking for content localization plugin, or how to write it.
Can add to the list django-i18n-model
I think you should operate in two steps:
Get translations
Show translated strings
For the first step, you should tell Django that the user-inserted strings are to be translated. I think there is no native way to do so. Maybe you can extract the strings from your db putting them in locale-specific files, run 'makemessages' on them, obtaint django.po files and translate.
Second, use ugettext to show those strings on your web application.
Hope this can help the ones with your same problem.
Or try this:
http://packages.python.org/django-easymode/i18n/index.html
It stays very close to how you would normally do a django model, you just add 1 decorator above your model. It has admin support for the translated fields, including inlines and generic inlines. Almost anything you can do with regular models and admin classes you can do with the internationalized versions.