I have the following problem:
I have two models: Article and Comment, in Comments, i have parent = models.ForeignKey(Article). I have it set up so that Comments is inline to ArticleAdmin(admin.ModelAdmin), and CommentInline(admin.StackedInline). What i would like is that for Article list view (elements chosen in list_display), I would like to display snippets of latest comments so that the user does not have to click into each individual comments to see the changes. Now i know that i can specify a function in list_display, but i'm not sure how to do what i wish to do easily in the functions.
anyone have any suggestion on how to go about accomplishing this?
Thank you very much for your help!
As you say, defining a function is the way to go - a custom method on the ModelAdmin class which takes the object as a parameter and returns a string representation of the latest comments:
class ArticleAdmin(admin.ModelAdmin):
list_display = ('name', 'latest_comments')
def latest_comments(self, obj):
return '<br/>'.join(c.comment for c in obj.comment_set.order_by('-date')[:3])
latest_comments.allow_tags = True
This takes the last three comments on each article, sorted by the 'date' field, and displays the comment field of each one, separated by an HTML <br> tag to show on one each line.
Related
I'm not entirely sure about the correctness of the question. In fact, I doubt whether I can express exactly what I am looking for.
Question: How can I create additional fields based on the previous selection before submitting the form?
Let's take the number of pets and the name of the pet in our example. I want how many pet names to be entered first
class UrlForm(forms.Form):
INT_CHOICES = [(x, x) for x in range(11)]
number_of_pets = forms.ChoiceField(choices=INT_CHOICES)
and then create as many Charfield fields as the selected value based on the previous selection:
#new fields as many as the number of pets
pet1 = forms.CharField()
pet2 = forms.CharField()
Of course, the variable name issue is a separate issue.
Question 2: As an alternative approach, can I create a pet name field like a tag field? As in the image:
Image taken from here. The question is appropriate but a ReactJs topic.
You can share the topic, title, term, article, anything that I need to look at. Thanks in advance.
Edit:
The pet example is purely fictional. Influenced by the image, I used this topic.
I have a form with only one field (name of family members).
class FamilyMemeberItem(forms.Form):
name= forms.CharField(label=_('name'), max_length=20)
Now I want my form be sorted (arbitrary order) defined by the user. For example in a family, I want to show A first, then B and then C, while the creation sequence may be C, B and A. Is there anyway to do that?
I searched and realized I should add an order field to my form and override the __iter__() method. Is that the only way? If there is no way to do that without change in form?
And could anyone please tell me about the field can_order of formset_factory? When I add it, an extra filed is loaded next to my form, and that's and integer presenting the number of that field. Can I change and save that so that the order changes?
I answered a similar question you posted.
I'll just repeat the last part here:
If you want to store the order in the database, you need to define a new field in you model and store the order in that. The order of formsets is only present inside a single request/response, after that its gone.
I want to incorporate a sorting feature which allows for multiple sorting variables.
I tried to pass .order_by() a function but it keeps failing when I try to include multiple fields. How do I do this?
if request.GET.get('size_sort')=='1':
def sorts():
sort='\'bedrooms\',\'bathrooms\''
return sort
posts=Post.objects.filter(**keyword_args).order_by(sorts())
This returns the traceback:
Invalid order_by arguments: ["'bedrooms','bathrooms'"]
See Django Book: Chapter 5 Models:
To order by multiple fields (where the second field is used to disambiguate ordering in cases where the first is the same), use multiple arguments:
That is, the correct invocation is:
order_by('bedrooms', 'bathrooms')
In context, consistent with the original question:
def sorts():
sort = ['bedrooms', 'bathrooms']
return sort
posts = Post.objects.filter(**keyword_args).order_by(*sorts())
Happy coding.
after wracking my brain for days, I just hope someone can point me to the right approach.
I have 4 Models: Page, Element, Style and Post.
Here is my simplyfied models.py/admin.py excerpt: http://pastebin.com/uSHrG0p2
In 2 sentences:
A Element references 1 Style and 1 Post (2 FKs).
A Page can reference many Elements, Elements can be referenced by many pages (M2M).
On the admin site for Page instances I included the M2M relation as 'inline'. So that I have multiple rows to select Element-instances.
One row looking like: [My Post A with My Style X][V]
What I want is to replace that one dropdown with 2 dropdowns. One with all instances of Post and one with all instances of Style (creating Element instances in-place). So that one row would look similar to the Element admin site: [My Post A][V] [My Style X][V]
Sounds easy, but I'm just completely lost after reading and experimenting for 2 days with ModelForms, ModelAdmins, Formsets, ... .
Can I do that without custom views/forms within the Django admin functionality?
One of my approaches was to access the Post/Style instances from a PageAdminForm like this, trying to create a form widget manually from it... but failed to do so:
p = Page.objects.get(pk=1)
f = PageAdminForm(instance=p)
f.base_fields['elements'].choices.queryset[0].post
Any advice or hint which way I need to go?
Thank you for your time!
I got exactly what I wanted after removing the M2M field and linking Elements to a Page with a 3rd ForeignKey in Element:
class Element(models.Model):
page = models.ForeignKey(Page)
post = models.ForeignKey(Post)
style = models.ForeignKey(Style)
Actually a non-M2M link makes more sense for my application after all.
Memo to self: Rethink model relations before trying to outsmart Django :-(
I'm using the object_list generic view to quickly list a set of Articles. Each Article has comments attached to it. The query uses an annotation to Count() the number of comments and then order_by() that annotated number.
'queryset': Article.objects.annotate(comment_count=Count('comments')).order_by('-comment_count'),
The comments are part of the django.contrib.comments framework and are attached to the model via a Generic Relationship. I've added an explicit reverse lookup to my Article model:
class Article(models.Models):
...
comments = generic.GenericRelation(Comment, content_type_field='content_type', object_id_field='object_pk')
The problem is, this counts "inactive" comments; ones that have is_public=False or is_removed=True. How can I exclude any inactive comments from being counted?
The documentation for aggregations explains how to do this. You need to use a filter clause, making sure you put it after the annotate clause:
Article.objects.annotate(comment_count=Count('comments')).filter(
comment__is_public=True, comment__is_removed=False
).order_by('-comment_count')