Pre-Filling a ForeignKey from a link to the Admin? - django

Some introduction. I have a "planet-like" feed aggregator with an extra layer on top. That extra layer allows for comments and elaboration on the aggregated posts. Here's some code for reference.
class Post(models.Model):
title = models.CharField()
published = models.DateTimeField()
class Story(models.Model):
title = models.CharField()
post = models.ForiegnKey(Post)
Story has a ForeignKey to Post and when I write a story I pick a post from the drop-down. Now, after a few weeks the list could get pretty unruly. I could use raw_id_fields, but that's a bit counter-intuitive since I would have to find the ID of the post I needed.
EDIT: After doing some research, I removed my misleading question. I'm wondering if something like this is possible (given that application is the name of my... application.
Write about this post.
Let me know if THIS needs any more explanation. :)

Looks like the admin recognizes GET values. So,
/admin/application/story/add/?post=[post.id]
would set post to the proper ID. :)

You might want to think about using an autocomplete field instead of raw_id_fields.
Jannis Leidel has a good explanation, with examples, on how to add auto-complete functionality to the djando admin exactly for cases like yours.
You will need to add jquery to the mix, but the process is not that complicated.

Related

Wagtail - passing queryset to inline

I am facing a problem from days, but, no matter how much I keep searching, I could not find any solution here or anywhere in the web.
So here it is: I am developing a website for some sort of institution which offers teaching courses. I am using WAGTAIL and I am structuring the classes this way:
class Course(Page):
...
content_panels = Page.content_panels
class Exam(Page):
#fields
content_panels = Page.content_panels + [
#fields
InlinePanel('preparatory_exam', heading='Preparatory Exams'),
]
class PreparatoryExam(Orderable):
page = ParentalKey('Exam',
on_delete=models.CASCADE,
related_name = 'preparatory_exams',
)
name = models.ForeignKey(
Exam,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name = 'preparatory_exam',
)
I also structured the ADMIN section PAGES this way:
\COURSE_1_PAGE
\-----------\EXAM_1
\-----------\EXAM_2
\------------------\Prep exam 1
\------------------\Prep exam 2
\-----------\EXAM_3
...
\COURSE_2_PAGE
\-----------\EXAM_1
\-----------\EXAM_2
\-----------\EXAM_3
....
So, the problem is: is there any way to pass a custom queryset to the inline dropdown box when choosing the preparatory exams for a certain one? What I want is to restrict the set to the exams present in the same Course.
I could do that with a limit_choices_to added to the foreignkey field, but AFAIK, it would be a "static" filter, because it would be related to the model and not to its istances, so it would be the same for every newly instantiated exam...
One first- highly unsatisfactory - solution would be to change the InlinePanel with 2-3 FieldPanels (generally an exam does not need more than 2-3 other prep exams)...
Another UGLY solution would be explicitly defining Course_1, Course_2 and so on classses, but the problem here is that every year I would have to add another class, because they set up a new course every year!
So it leaves me not a lot of choices: overriding somehow (but i'm in the dark) the InlinePanel object behavior, or change the way I designed the site.
Can anyone help me? Thank you very very much!
One pragmatic option might be to use "ordinary Django views" to build this particular part of the application, borrowing Wagtail visual designs freely so that everything continues to look the same to the end-user. Given that you are building a display of a very rigid data-structure - course, exam, etc., as opposed to "free-form content," this is probably how I would choose to do it.
(Note that Wagtail template tags might or might not work properly when Wagtail isn't the one driving the page display. I'd recommend implementing your own, of course freely copying from the Wagtail source-code for inspiration.) In the end, the user would not perceive a difference, and you can very freely develop URLs that would send the user to a Wagtail-managed target page, e.g. the course-descriptions and exams themselves.
Another pragmatic option is to use Django template-tags to construct portions of the display that are otherwise managed by Wagtail, although this gets maybe a bit more complicated. Since Django is underneath the whole thing, "Django rules still apply."

multi combo box in django

I have a model called Bar:
class Bar(models.Model):
country = models.CharField(max_length=20)
city = models.CharField(max_length=20)
name = models.CharField(max_length=20)
I want the user to be able to choose a bar through a combox box of first choosing a country, than a city (in that country), than a bar(in that city).
I tried doing it with django forms, but no success. What is the best way to do it? thanks
I think you should take a look on ChoiceField at Django Docs:
"(Default widget: Select)"
ChoiceField is rendered as select box in HTML. It should work for your case.
You should check out Django Smart Selects
PyPi
Blog post about implementation here
You can also fork it on GitHub I believe
I was recommended this in the past when I asked a similar question about How to create 'child' questions in Django forms? I never got a chance to play around with it but it seems very close to what you are looking for.
I was also never sure what to call this type of functionality but it seems like "Chained Select Boxes" which got from the above post is the best I've heard so far.

Design of models for better perfomance

My main task is to implement likes and comments in django application, but I have concerns regarding model structure and overall architecture of application.
What I want to achieve:
Basically I have only two models (for example Book and Author), which I want to be liked, shared and commented. So obviously, I need to create corresponding tables. The question is, how will be better to reference each Like, Share and Comment in Book and Author rows.
1-st solution: The first thing which came in mind is just to add corresponding ForeignKeys in Like, Share and Comment which will point to Author and Book. So, for example Like table will be in next form:
|---------|-----------|-----------|
| ID | AUTHOR_ID | BOOK_ID |
Where ID is id of Like, AUTHOR_ID and BOOK_ID are ForeignKeys to Author and Book rows.
The problem of this solution is that if you want to add ability to 'like' more stuff you will need to add new columns to Like table. I think this solution is hacky, since Like table can grow up very quickly.
2-nd solution: I have read this question where solution suggested to create a parent table, which can be liked and then inherit from it Book and Author tables.
This solution seems very nice to me, but now concern is about concrete inheritance in Django ORM. In book Two scoops of Django authors recommend to avoid it almost everywhere.
Could you please help me with advice, whether or not should I choose Multitable (Concrete) Inheritance in order to achieve what I want? Or maybe another, more beatiful and clean solution?
Thanks
This is exactly the sort of problem that generic relations were created to solve. The documentation on that link describes a tagging system, but it can just as easily be applied to likes.

django admin site: foreign key dropdown

For the django admin site, for example, I have a model as follow:
class Book(models.Model):
...
author = models.ForeignKey(Author)
...
(to make it simple, we assume each book only has one author)
So when I try to add a new Book in admin site, author will display as a dropdown list and I can roll and select the author it belong to.
The problem is that when you get a lot of Authors, it will be hard to find one you want. So someone suggest to use "raw_id_fields" to solve the problem.
I think it works. However, I want better. I want something like a search box inside the same page rather than pop a page to do so. And probably keep the dropdown list at the same time.
What I am thinking is that I probably need to write some customized template. I did some research on this, but I am still confused. I want to know which template I should override and what kind of approach I should use.
Thanks for any help!
There are several type-ahead / autocomplete plugins for Django admin that will take the place of the standard drop-down list. Here's a couple: https://github.com/artscoop/django-admin-autocomplete or https://github.com/sxalexander/django-autocomplete

Customize Django comments framework so that the comment does not have to be unique

I'm customizing the comments model per the Django documentation.
In my specific use case, however, comments are allowed to be blank. The trouble I get into then is that the Comment model is setup with an unique_together:
unique_together = [('user', 'comment', 'flag')]
Any ideas on how I could go about overriding this?
(...or did I start off on the wrong track with using the Comments framework altogether? :)
Doesn't look like the Comment model has a unique constraint.
Code for models.py for contrib.comments.
It looks like the CommentFlag model has the uniqueness constraint which shouldn't effect you having blank comments.
Your problem must lie elsewhere.
I'm not very familiar with the comments app but here are some ideas you can look at to get around your problem.
Warning I haven't used either of these methods on the comments app so I'm not sure if using these will break any downstream functions of the comments framework. Be sure to look into/test if you decide to use either of these.
That being said, I can think of 2 ways you can approach this.
Override the unique together:
class NonUniqueComment(Comment):
class Meta(Comment.Meta):
unique_together = []
Make the comments field store Null instead of empty string in the db.