Lets say I have a django model looking like this:
class question(models.Model):
order = models.IntegerField('Position')
question = models.CharField(max_length= 400)
answer = models.TextField()
published = models.BooleanField()
def __unicode__(self):
return self.question
In my view I show all of the questions ordered ascending by the order field.
My question is: Is there an easy way to edit the order field in the django admin interface? Right now, I have to go to edit the Question, then look up what number to put in the order field and maybe even reorder all the other items. What i really want would be some "up and down"-arrows on the admin page where all the questions are listed.
Is that possible?
Check this: django-orderedmodel.
This is a really simple implementation of abstract base class for items which can be ordered with admin interface. No external dependencies and easy to use.
Sure, here is an example of admin.py file with up and down links to change items order:
https://github.com/alexvasi/django-simplemenu/blob/master/simplemenu/admin.py
Basically, you just need to override get_urls method to add your custom views (move_up and move_down in this example).
More famous example would be django-treemenus, but there is some extra code to support older versions of django.
You can check:
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_editable
In case someone else is seeking the solution for that issue in 2017, I found the great package Django Admin Sortable
You can use django-admin-sortable2 to easily change the order of items including inline items as well.
Related
I was curious if there was a way to replicate the Django admin interface - specifically the forms when adding an object - in the front end... Here's my scenario:
class Area(models.Model):
name = models.CharField(max_length=100)
class SubArea(models.Model):
name = models.CharField(max_length=100)
area = models.ForeignKey(Area)
class Product(models.Model):
name = models.CharField(max_length=150)
area = models.ForeignKey(Area, null=True, blank=True)
subarea = models.ForeignKey(SubArea, null=True, blank=True)
So If I setup a form in the frontend for the Product model, I have no way of adding Area or SubArea objects. In the Django admin, however, I'm able to easily add these objects by clicking the "+" next to the fields.
I am looking for the easiest possible solution (while still being secure) to allow for fronted creating of the Foreign Keys without having to setup separate forms. Not sure if that is even possible, but wanted to reach out to the community for advice.
Thanks!
J
Django admin makes extensive use of formsets, see below:
https://docs.djangoproject.com/en/1.6/topics/forms/formsets/
Regarding your query with adding the '+' a la Django admin, you can acheive this with the RelatedFieldWidgetWrapper which you can find here.
According to my experience the easiest way of adding, editing, updating corresponding(related) items on a Form on the front-end, same way like in the django-Admin, is using "django-addanother" which you can use from here. Easy, fast and clean solution on this problem and it works with Django 1.11 too. And it has good documentation, demo also.
django-form-admin (.. let enter more characters stackoverflow needs 30 for answer)
I have a Question and Answer model as follows:
class Question(models.Model):
text = model.textField()
class Answer(models.Model):
question = model.ForeignKey(Question)
text = model.textField()
correct = model.BooleanField()
i want to save four answers while saving a question and in which only one answer can be correct. Also one answer must be correct out of four.
Well, I think your best option is to make use of Django Forms and do that validation on its clean method.
An example of its use can be found in https://docs.djangoproject.com/en/1.6/ref/forms/validation/ . It provides nice documentation and shows you how to validate fields on a form (which is what you need). If you don't know how to create a form, visit this https://docs.djangoproject.com/en/1.6/topics/forms/ first and then check out how it is done and check if it is what you were looking for. If it isn't, try to make your question a bit clearer, please =)
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.
How to filter objects with an "author" from a set of "authors"(Users)?
The "objects" are Posts, having an author(ForeignKey to User).
I'm pretty much stumped by this, so I'd appreciate help with it. Of course one could go about this the naive way, by manually filtering them, but that would hit the database real hard. Thanks anyway.
EDIT:
Listing of Post:
class Post(models.Model):
'''A Post or a Status Update.
'''
content=models.CharField(max_length=200)
author=models.ForeignKey(django.contrib.auth.models.User, related_name="author")
tags=models.ManyToManyField(Tag)
replyTo=models.ManyToManyField(django.contrib.auth.models.User, related_name="replyTo")
# Snip model methods
Clarification: I'm trying to filter based upon a set of users and not a single user (which is trivially easy to do)
when=models.DateTimeField(auto_now=True)
Thanks to everyone who helped with the previous question. Now I have one final thing to ask:
Code excerpt from UserProfile (connected to User):
def get_updates():
return Post.objects.filter(author__in=(list(self.friends.all()) + [self]))
Is this the most efficient way to get all the posts by an author and its friends? (Note: This is a naive implementation, as it doesn't handle pagination, etc. Will do that later)
Something like:
Post.objects.filter(author=user)
Where user is the relevant user should work, but it's hard to give a good answer with no models
EDIT
Now that I understand your question, try this:
Post.objects.filter(author__in=users)
Where users is the set of users
Post.objects.filter(author__in=setofusers)
Post.objects.filter(attribute__in = list_of_ids)
Say I have a Django class something like this:
class Person(models.Model):
name = models.CharField(max_length=50)
# ...
How can I programatically obtain the max_length value for the name field?
Person._meta.get_field('name').max_length will give you this value. But having to use _meta suggests this is something you shouldn't do in normal usage.
Edit: as Carl pointed out, this naming is misleading and it does seem quite acceptable to use it: http://www.b-list.org/weblog/2007/nov/04/working-models/
Read more at Django Docs:
https://docs.djangoproject.com/en/dev/ref/models/meta/#django.db.models.options.Options.get_field
The question is regarding models, but for people trying to do the same for forms (that's how I ended up in this thread), I think this approach is quite simple and clear:
1. In a template:
{{form.name.field.max_length}}
2. In python code (e.g. in the view)
form.name.field.max_length