Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
tayl0r
Oct 3, 2002
This post brought to you by SOE

bitprophet posted:

code:
class CodeStringMappings(models.Model):
    string_id = models.ForeignKey(Stringtable, blah blah blah)
Can you guess what the value of <CodeStringMappings instance>.string_id is going to be? Here's a tip: it's not an ID number.

Understood, but I still didn't know *how* to fix it.
After looking at my code this morning, I figured it out.

code:
    def __unicode__(self):
        return "%d: %s" % (self.string_id.id, self.message_name)
self.string_id is not a number, but self.string_id.id is.
Thanks for pointing me in the right direction, bitprophet.

Adbot
ADBOT LOVES YOU

bitprophet
Jul 22, 2004
Taco Defender

tayl0r posted:

Understood, but I still didn't know *how* to fix it.
After looking at my code this morning, I figured it out.

code:
    def __unicode__(self):
        return "%d: %s" % (self.string_id.id, self.message_name)
self.string_id is not a number, but self.string_id.id is.
Thanks for pointing me in the right direction, bitprophet.

I was trying to give you a nudge instead of spelling it out :)

ForeignKey attributes return other model objects; so naming ANY ForeignKey "something_id" is kind of silly/pointless/confusing to readers. Just call it "something" and reference it naturally, e.g. my_CodeStringMapping_object.string.some_attribute_on_the_related_String_object.

IIRC an automatic $name_id attribute will be added automatically, too, so that you will have access to $name (another model object) or $name_id (the integer ID value).

king_kilr
May 25, 2007

bitprophet posted:

IIRC an automatic $name_id attribute will be added automatically, too, so that you will have access to $name (another model object) or $name_id (the integer ID value).

This is correct.

Mashi
Aug 15, 2005

Just wanted you to know your dinner's cold and the children all agree you're a shitheel!
so king_kilr is right and my application structure sucks, can someone tell me how to solve the following:

Say most of your models have a many to many relationship with a Country model, which specifies which countries their objects are available in. Initially the country is detected using GeoIP but then the clients are forwarded to /{countrycode}/ and from then on their country is picked up from the URL, and all URLs printed out must be prefixed with the country code.

Calls to get_absolute_url() don't have any arguments so the model must check what countries it has associated and choose one to prefix the returned URL with. However, if the request URL is already prefixed with a country, we want to return that one.

There are many places in the application that want to be aware of this request data, just for convenience... Otherwise there are extra template tags to be written (which have access to the template context), more passing around of this data between views and models, and lots of instances in the templates where you want to print datetimes translated for a certain timezone.

Right now I am storing this data in such a way that makes my application non thread-safe, and this doesnt really matter but I want to know if there's any tricks for doing it that are both thread-safe and reduce boiler-plate code. Being able to create "per-request" template-tags would take me quite a long way, but I don't see how.

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.

Ansible posted:


Still a bit stuck on this but think I'm on the right track using model manager:

Whenever I reference a "Food" object, either through the Consumption model or directly, I want to have a few defined queries that will do some simple arithmetic and return a nutrient value. Nutrients are in value per 100g of Food, and modified by the measure and consumption amount.

So for example, when I loop through Consumption items, I want a Calorie query that will select a specific Nutrient item based on dynamic Food id and a static Nutr_Def id, then take (nutrient.value/100) * measure.grams * consumption.amount.

Is a model manager the correct way to do this, and if so should it be extending the Food model or should I put it in the consumption or measure models?

Ansible fucked around with this message at 21:51 on Apr 13, 2009

Mashi
Aug 15, 2005

Just wanted you to know your dinner's cold and the children all agree you're a shitheel!

Ansible posted:

Is a model manager the correct way to do this, and if so should it be extending the Food model or should I put it in the consumption or measure models?

I'm a bit confused about your particular case so here are some general tips, though I'd advise to take them with a pinch of salt and go with whatever is most natural for your application:

If you want to run a calculation of sorts (custom sql query or otherwise) on a particular instance of a model, make it an instancemethod for that model, and forget about managers. If you want to filter or load extra data via a queryset (before you are looping the instances) then user a manager.

If you have model A, and you want extra attributes that take model B into account loaded into a list of models A based on a queryset "extra" call or otherwise, you should put that into a manager of model A, because that's where your data is going to end up.

I find model managers to be a bit limiting sometimes you can only run one custom method per query, you can't chain them, but there is a simple way to achieve this if you need to, by extending the queryset for each model. See here.

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.

Mashi posted:

If you want to run a calculation of sorts (custom sql query or otherwise) on a particular instance of a model, make it an instancemethod for that model

Without using custom SQL, can I pull in related fields with an instance method? For example, with data like this (I simplified my tables for this example):



I have a page that displays Food details, called through the Measure model. So I pass an instance of Measure into my view, then display measure.food.name and measure.name in my template. I also want to show the calories and nutrients included in that measure of that food.

Is it possible to add an instancemethod to Measures with something like:

code:
class Measure(models.Model):
    food = models.ForeignKey(Food)
    name = models.CharField(max_length=20)
    ...
    def calories(self):
        return self.grams * self.food.cals / 100
And then call that in my template with measure.calories ? I appreciate the help; my dev time is pretty limited so anything that I can resolve throughout the week helps me out a ton.

king_kilr
May 25, 2007
Sure, that would work just as you suggested, in teh template it's just

{{ measure.calories }}

No need for the ()

Mashi
Aug 15, 2005

Just wanted you to know your dinner's cold and the children all agree you're a shitheel!

Ansible posted:

Without using custom SQL, can I pull in related fields with an instance method? For example, with data like this (I simplified my tables for this example):

Measures.objects.select_related('food') will produce a join on your food table which loads the related food instances in bulk, rather than running individual queries for them when they are accessed via the measure instances.

Wulfeh
Dec 1, 2005

The mmo worth playing: DAoC

Mashi posted:

Measures.objects.select_related('food') will produce a join on your food table which loads the related food instances in bulk, rather than running individual queries for them when they are accessed via the measure instances.

This needs to be stressed, if you fail to implement this you are going to be making a ridiculous amount of unneeded queries to the database.

king_kilr
May 25, 2007

Wulfeh posted:

This needs to be stressed, if you fail to implement this you are going to be making a ridiculous amount of unneeded queries to the database.

No, what needs to be stressed is that that doesn't change the results returned, it is merely an optimization, start righting your site without any optimizations, and add as needed, if you just start sticking select_related throughout your code wiht no thought you are going to generate lots of massive joins that are far worse than extra queries.

Mashi
Aug 15, 2005

Just wanted you to know your dinner's cold and the children all agree you're a shitheel!

king_kilr posted:

No, what needs to be stressed is that that doesn't change the results returned, it is merely an optimization, start righting your site without any optimizations, and add as needed, if you just start sticking select_related throughout your code wiht no thought you are going to generate lots of massive joins that are far worse than extra queries.

I know theres a good argument for avoiding joins on really high load sites but I think you should explain a little better what you mean. If you mean that nobody should make a habit of using "select_related()" (without arguments) because they think that the cost of queries is more linear than it is, then I agree, but I would prefer to use select_related to join one or two tables if it's going to save 30-n00 "select * from table where id=" type queries.

king_kilr
May 25, 2007
My argument is not that you should never use select_related, it's that you should build your website without it and add it back in as necessary, because it's way to easy to create a view that uses select related because you expect to present your data one way, and then change how it's presented, which leaves you with a select_related call doing extraneous joins. Premature optimization is the root of all evil.

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.
A given measure instance only links to one food (since the grams per measure varies between foods), so I don't think using select_related would be an optimization unless I'm misinterpreting it? If I'm correct, I would use it in the case where I'm looping through a one-to-many relationship ya?

Wulfeh
Dec 1, 2005

The mmo worth playing: DAoC

king_kilr posted:

No, what needs to be stressed is that that doesn't change the results returned, it is merely an optimization, start righting your site without any optimizations, and add as needed, if you just start sticking select_related throughout your code wiht no thought you are going to generate lots of massive joins that are far worse than extra queries.

I agree, but it is an easy optimization to make if you know you going to be using those relations and you are loading several instances of that model.

Pagan
Jun 4, 2003

I've run into a problem that's got me stumped.

http://pastebin.com/m15a8bbc9

I've got two forms, my mainform and ingredform. If both are "active" in the html, then neither form will submit properly. If I comment out one or the other, each form works properly by itself.

The error I'm getting is : raise ValidationError('ManagementForm data is missing or has been tampered with')

Searching for that in documentation brings me to this page : http://docs.djangoproject.com/en/dev/topics/forms/formsets/#id2 which talks about the managementForm data, but that data does exist in my page; it's even showing up on the error screen.

I'm stumped, and if it's something simple, I'm just not seeing it.

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.
What does your forms.py look like?

Pagan
Jun 4, 2003

Ansible posted:

What does your forms.py look like?

I have everything in models.py, which I added to the pastebin.

http://pastebin.com/m4fa8aff4

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.
You aren't passing the prefix into the context so it can't properly process the management form:

code:
        return render_to_response("recipeformtest.html", {
        ...
        "ingredformset" : IngredUsedFormSet(queryset=IngredientsUsed.objects.filter(recipeid__exact=recipetag)),
        ...        })
 
Change that to

code:
        return render_to_response("recipeformtest.html", {
        ...
        ingredformset" :  ingredformset
        ...       })
 
And you should be golden.

Pagan
Jun 4, 2003

edit : Figured it out! I made one form, instead of two, and it works.

Pagan fucked around with this message at 23:09 on Apr 18, 2009

king_kilr
May 25, 2007
Google Summer of Code has announced the selected projects and Django is participating again this year: http://socghop.appspot.com/org/home/google/gsoc2009/django . Last year brought us great stuff like the comments rewrite and aggregation/query expressions. I've been accepted to work on multiple database support so if that's something you need please follow along on django-dev(or ping me here) since I'll be sending an email to -dev every week starting this week to discuss the status of that including the API.

ATLbeer
Sep 26, 2004
Über nerd

king_kilr posted:

Google Summer of Code has announced the selected projects and Django is participating again this year: http://socghop.appspot.com/org/home/google/gsoc2009/django . Last year brought us great stuff like the comments rewrite and aggregation/query expressions. I've been accepted to work on multiple database support so if that's something you need please follow along on django-dev(or ping me here) since I'll be sending an email to -dev every week starting this week to discuss the status of that including the API.

A "bug" (almost) I ran into recently was having to do with date handling in Django. It's great to be able to find all messages from a certain month or day (e.g. Message.objects.filter(DateCreated__month=1, etc) but, the resolution of the search to only days creates a tricky situation when your dealing with more granular data.

You can't do searches for items for the last hour for example
code:
from datetime import datetime
now = datetime.now()
Message.objects.filter(DateCreated__month=now.month, 
                       DateCreated__day=now.day, 
                       DateCreated__year=now.year, 
                       DateCreate__hour=now.hour)
The problem, I believe, has to do with some database dependencies behind the QuerySet abstraction layer. Why I bring this up is that my solution to this problem (which I believe also allows it to be a bit transportable across RDBMS) is to use unix time as a date/time store instead of MySQL Time. If your time is stored as an unix time double it allows you a very fine resolution for queries (to the microsecond?).

I'm not sure what other project dependancies there are in changing the time storage technique or if this should be resolved by a new model type like PreciseDateTimeModel, etc instead of reworking QuerySet to a different date/time format.

Just throwing it out there as something I ran into recently.

king_kilr
May 25, 2007
Hrm, a change like that would almost certainly be rejected for Django itself since it would break backwards compatibility, however you could write your own DateField implementation that looked exactly like the Django one except it stored data as a Unix timestamp, see http://docs.djangoproject.com/en/dev/howto/custom-model-fields/

EDIT: Also, if all the backends actually support extracting the hour out of a datetime field there's no reason you couldn't propose just that addition.

ATLbeer
Sep 26, 2004
Über nerd

king_kilr posted:

Hrm, a change like that would almost certainly be rejected for Django itself since it would break backwards compatibility, however you could write your own DateField implementation that looked exactly like the Django one except it stored data as a Unix timestamp, see http://docs.djangoproject.com/en/dev/howto/custom-model-fields/

EDIT: Also, if all the backends actually support extracting the hour out of a datetime field there's no reason you couldn't propose just that addition.

MySQL doesn't support hour in it's datetime implementation. :(

I might write up a custom model. I've basically added the logic adhoc in a model manager off a DecimalField.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

ATLbeer posted:

MySQL doesn't support hour in it's datetime implementation. :(

I might write up a custom model. I've basically added the logic adhoc in a model manager off a DecimalField.

MySQL has HOUR() which when applied to a datetime value gives you the hour.

Mashi
Aug 15, 2005

Just wanted you to know your dinner's cold and the children all agree you're a shitheel!

ATLbeer posted:

You can't do searches for items for the last hour for example

You can't use range for that?

code:
now = datetime.datetime.now()
Message.objects.filter(date__range=(now,
                                    now - datetime.timedelta(mins=60)))
edit: actually, if you need to do a lookup based on date/time, you should always use range unless you need say every message ever posted on a Sunday.

Mashi fucked around with this message at 04:53 on Apr 21, 2009

mister_gosh
May 24, 2002

I'm just starting out. Can anyone give me a broad idea of things I should be aware of when writing a Django application with pre-existing database tables?

Based on what I read yesterday, it takes away part of the purpose of the model.py script because that is where you define your tables. I can define them in model.py and if they exist already, it won't attempt to create them will it? Or does it prepend "django_" onto the name of each table?

king_kilr
May 25, 2007
You can use Django with a legacy database, there are options to control the database table and the field name for each field. The main limitation is that composite primary key's aren't supported. There's also the insepect db management command for trying to create a models.py file from your database automatically:

http://docs.djangoproject.com/en/dev/ref/django-admin/#inspectdb

mister_gosh
May 24, 2002

Thank you, looks like exactly what I'm looking for. I'm running it (manage.py inspectdb) and despite it looking like it is doing stuff, I'm not seeing a model.py appear in my project or app dir.

Considering this is my second day of looking at django, I'd say I probably just don't know what I'm doing yet. I'll come back if I really can't figure it out.

vvvv Thanks! vvvv

mister_gosh fucked around with this message at 20:06 on Apr 21, 2009

king_kilr
May 25, 2007
It outputs the models.py "file" to stdout, it doesn't actually create a file for you.

FuncType
Mar 29, 2007

Tactical Wiener Lover
I am just getting myself setup with Django and Python in general. I've run into a small wall with getting Python working with apache2.2. I have installed Python 2.6.2, have the latest Django from svn, which works just fine out of the box. It looks to me like mod_python does not support Python 2.6 at this time. Am I better served to just go back to the latest 2.5 branch, or is there something I can do to stay on the most up-to-date Python release?


EDIT: It appears that after a bit more reading, I was beating my head against the wall. Going with mod_wsgi.

FuncType fucked around with this message at 21:08 on Apr 21, 2009

No Safe Word
Feb 26, 2005

zycl0n posted:

EDIT: It appears that after a bit more reading, I was beating my head against the wall. Going with mod_wsgi.
Ding ding ding. This is the correct choice.

http://docs.djangoproject.com/en/dev/howto/deployment/ posted:

If you’re new to deploying Django and/or Python, we’d recommend you try mod_wsgi first. In most cases it’ll be the easiest, fastest, and most stable deployment choice.

mod_python is kind of a pain in the rear end, to be quite honest

jupo
Jun 12, 2007

Time flies like an arrow, fruit flies like a banana.

No Safe Word posted:

mod_python is kind of a pain in the rear end, to be quite honest

Can you clarify further on this? I don't have any experience with mod_wsgi and I've never had a problem with mod_python - I'm genuinely curious.

mister_gosh
May 24, 2002

EDIT: Nevermind, I'm dumb. You have to run syncdb before attempting to run inspectdb

I had had some minor problems with python and Django and my mod_python integration didn't seem to be working quite right. Based on the above statements, I decided to flush my system of any and all python stuff and start over. Plus, I was using Python 2.5, mod_python rather than mod_wsgi, Apache was 2.0 rather than 2.2, etc.

So, I'm now at Python 2.6.1, cx_Oracle 4.4.1 and Django 1.0.2.

The problem now is I can't seem to get Django to run inspectdb. It ran fine before, but now it just sits there and hangs. I thought it may actually be connecting to the database, but the legacy db has a lot in it so I let it sit/hang overnight, to no avail.

I'm running: python manage.py inspectdb

I tested out a .py script I have which connects to the db and runs some queries and it works fine, so I think it must be a django configuration problem.

This morning I attempted to flush out the database of django tables from the previous install. I cleared out the auth_* and django_* tables but that didn't seem to help. Is there a list of tables out there than django creates and uses? - and more importantly, does anyone have an idea why inspectdb may not be running?

mister_gosh fucked around with this message at 16:50 on Apr 23, 2009

Ansible
Sep 11, 2003

This is what I get for trusting other people to give me stuff. And that's why I'm so lucky.
I love Django.

Built out custom instance methods as was recommended (i'll optimize with select_related in the future), and now most everything works together very cleanly. However, I ran into a small problem working with these methods and know there has to be a better way to do this, but I don't see what I'm missing. Right now my methods are:

code:
# Consumption Model
class Consumption(models.Model):
    person 		= models.ForeignKey(User)
    measure		= models.ForeignKey(Measure)
    amount 		= models.DecimalField(max_digits=5,decimal_places=2)
    date 		= models.DateField()
    meal 		= models.CharField(max_length=10, choices=MEAL_CHOICES, blank=True)

    def calories(self):
        return round(self.amount * self.measure.grams * self.measure.food.calories / 100,2)
    def protein(self):
        return round(self.amount * self.measure.grams * self.measure.food.protein / 100,2)
    def fat(self):
        return round(self.amount * self.measure.grams * self.measure.food.fat / 100,2)
    def carbs(self):
        return round(self.amount * self.measure.grams * self.measure.food.carbs / 100,2)
    p_calories = property(calories)
    p_protein = property(protein)
    p_fat = property(fat)
    p_carbs  = property(carbs)
And then in a view I want a sum of each nutrient for the period being viewed. Right now I am using:

code:
 my_consumption = Consumption.objects.filter(person=request.user).order_by('-date')
 my_calories = 0
 for consumption in my_consumption:
 my_calories = my_calories + consumption.p_calories
I don't really understand having to call the property instead of the method but it works. I also don't understand why I can't do something like:

code:
 my_consumption = Consumption.objects.filter(person=request.user).order_by('-date')
 my_calories = sum(my_consumption.p_calories)
Since that queryset should be iterable, right?

I'm also trying to do a general group_by(date) view that sums the nutrients. Is the best route here to use custom SQL? I notice that the dev release of django has some nice aggregation functions but I'd prefer to stick with 1.0 for now.

mister_gosh
May 24, 2002

edit2: thought I fixed it, but I actually made it worse, help anyone?

I have tried unsuccessfully all day to configure mod_wsgi, apache, django and python with no luck. I have tried various sites and googling. I regret messing with my working configuration.

Anyways, can anyone take a look and try to see where I may be doing something wrong?

I put mod_wsgi.so into the modules directory.

Configured httpd.conf like so:

httpd.conf:
code:
LoadModule wsgi_module modules/mod_wsgi.so

...

Alias /acme_usage_metrics/ "D:/dev/python/acme/acme_usage_metrics/"

<Directory "D:/dev/python/acme/acme_usage_metrics">
    Order deny,allow
    Allow from all
</Directory>


WSGIScriptAlias / "D:/dev/python/acme/apache/django.wsgi"

<Directory "D:/dev/python/acme/apache">
Order deny,allow
Allow from all
</Directory>
I then created the file D:/dev/python/acme/apache/django.wsgi.
django.wsgi
code:
import sys
import os
sys.path.append('D:/dev/python/acme')
os.environ['DJANGO_SETTINGS_MODULE'] = 'acme.settings'
       
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Modified D:\dev\python\acme\settings.py

settings.py
code:
...
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'acme.acme_usage_metrics',
)
I'm confused how to make a hello world script, but I don't think I'm getting that far. I had previously got a hello world to work with mod_python.

Anyways, the problem is, initially when I went to http://127.0.0.1 it displayed a page saying "It works!". Now it doens't even say that.

I get:

quote:

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, admin@net.plm.eds.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

Apache's error.log says:
code:
mod_wsgi (pid=7852): Target WSGI script 'D:/dev/python/acme/apache/django.wsgi' cannot 
                     be loaded as Python module.
 mod_wsgi (pid=7852): Exception occurred processing WSGI script 
                      'D:/dev/python/acme/apache/django.wsgi'.
 Traceback (most recent call last):
   File "D:/dev/python/acme/apache/django.wsgi", line 6, in <module>
     import django.core.handlers.wsgi
   File "C:\\Python26\\lib\\site-packages\\django\\core\\handlers\\wsgi.py", line 8, in <module>
     from django import http
   File "C:\\Python26\\lib\\site-packages\\django\\http\\__init__.py", line 5, in <module>
     from urllib import urlencode
   File "C:\\Python26\\lib\\urllib.py", line 26, in <module>
     import socket
   File "C:\\Python26\\lib\\socket.py", line 46, in <module>
     import _socket
 ImportError: DLL load failed: The specified module could not be found.
I tried typing "import _socket" in python and it resolves just fine.

Help? :(

mister_gosh fucked around with this message at 01:24 on Apr 24, 2009

mister_gosh
May 24, 2002

mister_gosh posted:

I then created the file D:/dev/python/acme/apache/django.wsgi.
django.wsgi
code:
import sys
import os
sys.path.append('D:/dev/python/acme')
os.environ['DJANGO_SETTINGS_MODULE'] = 'acme.settings'
       
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Fixed it by changing sys.path.append('D:/dev/python/acme') to sys.path.append('D:/dev/python')

geera
May 20, 2003
So I'm trying to set up the Django documentation for offline use, and I'm having a lot of trouble with the whole sphinx build process. I've tried installing sphinx with apt-get like one tutorial suggested, but that wanted to download 20 packages of other stuff (including Apache... ?) to go along with it. Then I tried using easy_install, which downloaded Sphinx but threw up a bunch of gcc errors on some other package called Jinja. This is on Ubuntu 8.10 with Python upgraded to 2.6.

All I want is a copy of the documentation in HTML that I can refer to while I'm on a plane trip. Why do I have to install utilities and compile text files, can't they just make a tar/zip file available with the HTML docs already provided?

king_kilr
May 25, 2007
Just apt-get install python-sphinx. cd django_src/docs; make html; firefox _build/html/index.html

This entire process is about 30 seconds on my machine.

Adbot
ADBOT LOVES YOU

geera
May 20, 2003
I think the problem is that I upgraded to 2.6 from source, but apt-get thinks I'm still running the stock 2.5 that came with Ubuntu. So I get this error for every one of the dependencies it tries to install along with python-sphinx:

quote:

ValueError: /usr/bin/python does not match the python default version. It must be reset to point to python2.5

Any suggestions would be appreciated!

Edit: looks like changing the symlink for python back to python2.5, doing apt-get install python-setuptools, and doing easy_install Sphinx again finally worked. All the docs are compiled now.

geera fucked around with this message at 16:24 on Apr 29, 2009

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply