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
MonkeyMaker
May 22, 2006

What's your poison, sir?

fletcher posted:

From the Model.clean docs:


So I've got:

Python code:
class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    full_name = models.CharField(max_length=201)

    def clean(self):
        self.full_name = self.first_name + ' ' + self.last_name
Then in the admin console:
code:
>>> joe_schmoe = Person.objects.get(full_name='Joe Schmoe')
>>> joe_schmoe.first_name = 'Joseph'
>>> joe_schmoe.save()
>>> Person.objects.get(full_name='Joseph Schmoe')
DoesNotExist: Person matching query does not exist.
What's the point of using a Model.clean() override to set full_name if Model.save() doesn't invoke it?

Model.clean() is kind of a lovely little snippet. It only gets called by ModelForm.clean() and, even then, isn't super-reliable.

If you want to custom calculate a field on a model, do it in the save() method.

Adbot
ADBOT LOVES YOU

Smarmy Coworker
May 10, 2008

by XyloJW
Django friends itt:
what is best in life, Django or Python-Twisted? I've never Django'd before.

Tavistock
Oct 30, 2010



They do different things. Ones for doing async web server while django is a framework for creating websites. Django uses at a lower level a web server to handle requests but mostly that sort of stuff is abstracted away from a django user. The best way to get a hang of what I mean is to go and do the poll tutorial on the django website. But yea django is best in life but so is python-twisted and;

Smarmy Coworker
May 10, 2008

by XyloJW
okay, so if I didn't really want to get heavy into async web stuff which I did on my job, for a personal website, I should maybe use Django?

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Smarmy Coworker posted:

okay, so if I didn't really want to get heavy into async web stuff which I did on my job, for a personal website, I should maybe use Django?

If it needs a database, sure.

Smarmy Coworker
May 10, 2008

by XyloJW
golden

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
Hey folks, I'm having a weird issue that I was hoping for some help with.

I have a model with clean() and validate_unique(). When the model is invalid I raise a ValidationError in these methods as per the documentation.

However, when I create a model that's invalid from the admin panel, I get
code:
'ValidationError' object has no attribute 'error_dict'
and the model doesn't get saved.

Does anyone know how to resolve this issue?

Yay
Aug 4, 2007

MonkeyMaker posted:

Model.clean() is kind of a lovely little snippet. It only gets called by ModelForm.clean() and, even then, isn't super-reliable.
its only really lovely* because 5 versions later, it's still not called by default (nor is full_clean), presumably still in the misguided name of backwards compatibility.

As someone who does call full_clean mostly, I'd be keen to know in what way you're suggesting it's not reliable, as it's not something I've ever knowingly come across.

* actually, model validation is also lovely because it has a different API to forms. An API which has remained stable and flexible for ... 7 versions?

Ahz
Jun 17, 2001
PUT MY CART BACK? I'M BETTER THAN THAT AND YOU! WHERE IS MY BUTLER?!
Does anyone know the best go-to library or whatever to generate custom QR codes?

I'm looking to generate and then store the GIF or whatever they create as a binary in postgres.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Ahz posted:

Does anyone know the best go-to library or whatever to generate custom QR codes?

I'm looking to generate and then store the GIF or whatever they create as a binary in postgres.

Out of curiosity, what do you want to use the QR codes for? I only ask because I've never seen somebody point their phone at one before.

PNG (or even SVG?) would be a much better format for QR codes than GIF I would think.

There seems to be no shortage of libraries for QR codes on PyPi:

https://pypi.python.org/pypi/qrcode
https://pypi.python.org/pypi/django-qrcode

Ahz
Jun 17, 2001
PUT MY CART BACK? I'M BETTER THAN THAT AND YOU! WHERE IS MY BUTLER?!
Yeah I found those libraries, they seem to work fine, thanks.

They're a bit of a fad, but I don't think they're going away and only going to become more ubiquitous as they become a more accepted standard for mobile input. Ironically in my quest to find a good qrcode generating library for python, I decided to just do QR generation on the fly on iOS/Android itself instead of server-side.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

Yay posted:

* actually, model validation is also lovely because it has a different API to forms. An API which has remained stable and flexible for ... 7 versions?

Yeah, what's the deal with this? You'd think more effort would be put into something that promotes DRY principles.

Basically I don't want to write separate form validation for my admin form and my application form and the fact that it's like pulling teeth is frustrating to say the least.

MonkeyMaker
May 22, 2006

What's your poison, sir?

Blinkz0rz posted:

Yeah, what's the deal with this? You'd think more effort would be put into something that promotes DRY principles.

Basically I don't want to write separate form validation for my admin form and my application form and the fact that it's like pulling teeth is frustrating to say the least.

Just make your Model.save() check for Model.clean() before it saves, obv.

(I've, sadly, done that before)

---

Also, I gave a tutorial yesterday at PyCon (if you're here, say hi). If any of you want the book I wrote for it, it's here as a PDF or here as HTML

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

MonkeyMaker posted:

Just make your Model.save() check for Model.clean() before it saves, obv.

(I've, sadly, done that before)

To be honest, the issue I'm running into is raising multiple ValidationError exceptions from the model.clean() and model.validate_unique() methods.

You'd think the error dictionary would work correctly, but it seems like there's a minor difference in the way the model instance is handled when it's being returned from model validation versus form validation.

Any thoughts on how to handle that? I was thinking I could write stubs for the form that implement full_clean() and then handle the exceptions when they bubble up, but I really do want to adhere to DRY.

more like dICK
Feb 15, 2010

This is inevitable.

MonkeyMaker posted:

Just make your Model.save() check for Model.clean() before it saves, obv.

(I've, sadly, done that before)

---

Also, I gave a tutorial yesterday at PyCon (if you're here, say hi). If any of you want the book I wrote for it, it's here as a PDF or here as HTML

I'm at Pycon! I'll say hello awkwardly if I see you.

MonkeyMaker
May 22, 2006

What's your poison, sir?

more like dICK posted:

I'm at Pycon! I'll say hello awkwardly if I see you.

I'll be in the board game open space this evening. Come by!

blinkz0rz posted:

To be honest, the issue I'm running into is raising multiple ValidationError exceptions from the model.clean() and model.validate_unique() methods.

You'd think the error dictionary would work correctly, but it seems like there's a minor difference in the way the model instance is handled when it's being returned from model validation versus form validation.

Any thoughts on how to handle that? I was thinking I could write stubs for the form that implement full_clean() and then handle the exceptions when they bubble up, but I really do want to adhere to DRY.

Not really. I don't think I've ever really used Model.validate_unique().

There isn't a model instance being returned from form validation, though. It's actually a ModelForm instance which is "saved" before the model is written to the db itself. It's a weird process but seems to work.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
I ended up moving my uniqueness test (Model.validate_unique()) into clean() even though the docs say I should separate them. Everything works now. Weird that raising multiple ValidationError exceptions in separate validation methods would blow up so spectacularly.

MonkeyMaker
May 22, 2006

What's your poison, sir?
If you missed PyCon 2014 (or just the tutorials or whatever), lots of the videos are online. Two of the Django tutorials:

Django for Web Designers and Front End Developers by Tracy Osborn

Getting Started with Django: A Crash Course by me.

Pollyanna
Mar 5, 2005

Milk's on them.


I'm going to cry. How do I get a traceback in Foreman/Heroku logs for Django? I'm getting a Server Error 500 in Foreman when everything works perfectly on a local server.
I can't figure out why it's breaking without knowing what's erroring out. Unfortunately, all I get from Foreman is:

code:
17:45:34 web.1  | started with pid 79852
17:45:34 web.1  | 2014-04-15 17:45:34 [79852] [INFO] Starting gunicorn 18.0
17:45:34 web.1  | 2014-04-15 17:45:34 [79852] [INFO] Listening at: [url]http://0.0.0.0:5000[/url] (79852)
17:45:34 web.1  | 2014-04-15 17:45:34 [79852] [INFO] Using worker: sync
17:45:34 web.1  | 2014-04-15 17:45:34 [79855] [INFO] Booting worker with pid: 79855
and nothing else. Heroku logs aren't much help either:

code:
request_id=ef7d2d17-4b62-4118-9bd4-2d8cd2d9ba56 fwd="98.231.79.0" dyno=web.1 connect=12ms service=25ms status=200 bytes=1438
2014-04-15T21:32:30.335248+00:00 heroku[router]: at=info method=POST path=/hangman/login/ host=app-tracker.herokuapp.com request_id=27ff9f9b-9574-4379-9705-cc3957971555 fwd="98.231.79.0" dyno=web.1 connect=65ms service=275ms status=200 bytes=1454
2014-04-15T21:32:30.303270+00:00 app[web.1]: <ul class="errorlist"><li>__all__<ul class="errorlist"><li>Please enter a correct username and password. Note that both fields may be case-sensitive.</li></ul></li></ul>
2014-04-15T21:32:33.135941+00:00 heroku[router]: at=info method=POST path=/hangman/login/ host=app-tracker.herokuapp.com request_id=e23d79e1-ab2e-4a0f-8c9c-fd79190b5105 fwd="98.231.79.0" dyno=web.1 connect=11ms service=222ms status=302 bytes=521
2014-04-15T21:32:33.614881+00:00 heroku[router]: at=info method=GET path=/hangman/ host=app-tracker.herokuapp.com request_id=9e069246-6fcc-494a-887f-d6c27d3a3b4e fwd="98.231.79.0" dyno=web.1 connect=14ms service=304ms status=500 bytes=251
Is there a way to get a real trace stack from Foreman? Cause I need to know why this isn't working.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
What does your logging config look like in Django?

I have this in mine and it sends me an email with the full stack trace and all kinds of useful information if somebody hits a 500 error:

code:
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

Pollyanna
Mar 5, 2005

Milk's on them.


Um, I don't. How do I use that?

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Put it in your settings.py file

Pollyanna
Mar 5, 2005

Milk's on them.


So this sends you an email, correct? The documentation mentions something about adding logger functions to the views. Do I need to include that as well, or does Django automatically handle stacktraces and email them?

Also, I assume it won't send an email from Foreman, and only off of the herokuapp server?

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Aw crap I thought it would be easy to send email on Heroku but apparently it's not, you have to use a third party SMTP provider: https://devcenter.heroku.com/articles/smtp

Django can then be configured to use that third party SMTP server: https://docs.djangoproject.com/en/dev/topics/email/

So maybe not the route you want to go down right now if we're just trying to debug this 500 error. Regardless, to answer your logger functions in the views question, you don't have to do that stuff for the email alerts I was talking about.

I'm actually not familiar with foreman at all, so not sure on that one. Sorry :(

I think your solution is probably in the logging configuration though.

Pollyanna
Mar 5, 2005

Milk's on them.


Don't worry about it, I figured I can store the log as a file. I managed to track it down to a South fuckup :argh: I ended up wiping the database and starting over, but hooray, it works! Thanks a bunch.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

FYI, it's really easy to set up django send grid on heroku to send emails. Just google it and you'll be running all quick like.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Python code:
def generate_photo_filename(instance, filename):
    image = Image.open(???)
    ext = image.format
    filename = '%s.%s' % (uuid.uuid4(), ext)
    return os.path.join('myproject/photos', filename)


class Person(models.Model):
    name = models.CharField(max_length=75)
    profile_photo = models.ImageField(upload_to=generate_photo_filename)
    cover_photo = models.ImageField(upload_to=generate_photo_filename)
I wanted to handle the scenario where somebody uploads whatever.jpg but it's actually a gif file.

What goes in the question marks? How does generate_photo_filename know if it's handling profile_photo or cover_photo? I could just make separate functions for upload_to, wondering if there is a better way to handle this though.

edit: and I suppose .jpg is just slightly more correct than .jpeg, but whatever we can ignore that for now

fletcher fucked around with this message at 02:47 on Apr 17, 2014

raymond
Mar 20, 2004

fletcher posted:

wondering if there is a better way to handle this though

I've not used it but this is what I would do:

https://github.com/iserko/django-storages/blob/master/storages/backends/image.py

You can use custom storage objects like:
Python code:
image_storage = ImageStorage(location='/myproject')

class Person(models.Model):
    name = models.CharField(max_length=75)
    profile_photo = models.ImageField(upload_to='photos/people', storage=image_storage)
    cover_photo = models.ImageField(upload_to='photos/people', storage=image_storage)

raymond fucked around with this message at 16:01 on Apr 17, 2014

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
What's the best way to create this setup:

Entry - rating - User?

Entry has ratings, User also has ratings that s/he has made of entries. (Also should I extend the base User class?) Currently I have a Rating class that has User and Entry as ForeignKeys, but I'm not sure how to handle Entry. Should it have a ManyToManyField "ratings" variable (even though a Rating can belong only to one Entry)? Also each Rating object can be made only by a single User.

I'm sure this stuff is handled daily by experienced coders, so how? (The purpose of the arrangement is obviously to ensure that one user gets one vote/rating.)

Pollyanna
Mar 5, 2005

Milk's on them.


Each Rating belongs to one User and to one Entry, I suppose? Each Entry and each User can Have Many Ratings, but each Rating has one associated Entry and one associated User. So the Rating would have a Foreign Key to a user and a Foreign Key to an Entry, and both Entries and Users have one-to-many fields for Ratings.

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
I didn't see a one-to-many field in Django documentation, and was rather saddened by it. Or am I missing something?

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

supermikhail posted:

I didn't see a one-to-many field in Django documentation, and was rather saddened by it. Or am I missing something?

django.db.models.ForeignKey()

supermikhail
Nov 17, 2012


"It's video games, Scully."
Video games?"
"He enlists the help of strangers to make his perfect video game. When he gets bored of an idea, he murders them and moves on to the next, learning nothing in the process."
"Hmm... interesting."
I don't get it. It says it's many-to-one, not the other way around, and my google-fu suggest they are not the same... Okay, I've managed to dig up the fact that there is a "Related objects' manager", which ensures that a ForeignKey relationship gets "two-way traffic". I didn't realize that but the fact that the tutorial's "question" had access to "choice_set" was a bit suspicious.

Thanks for making me stare in the right direction for long enough! :)

Ahz
Jun 17, 2001
PUT MY CART BACK? I'M BETTER THAN THAT AND YOU! WHERE IS MY BUTLER?!
You're own structure is a many-to-many structure, a real one, not the hacky thing Django calls its own one.

You're right, you use the related manager to traverse the reverse relationship. I prefer to use the 'related_name' attr to make traversal a little more obvious when coding rather than the default *_set.

more like dICK
Feb 15, 2010

This is inevitable.
Is there an easy way to do periodic tasks in Django that doesn't involve Celery and works on Python 3.3+? I'll use Celery if that's what it comes down to, I'm just a bit sick of janitoring init scripts.

MonkeyMaker
May 22, 2006

What's your poison, sir?

more like dICK posted:

Is there an easy way to do periodic tasks in Django that doesn't involve Celery and works on Python 3.3+? I'll use Celery if that's what it comes down to, I'm just a bit sick of janitoring init scripts.

Have cron call a management command?

more like dICK
Feb 15, 2010

This is inevitable.
Oh wow I totally forgot you can write custom manage.py commands. That simplifies things immensely.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Is it necessary to make a South migration for something like python-social-auth? If you just do a pip install python-social-auth and then ./manage.py schemamigration social.apps.django_app.default --initial, I think the migration file ends up somewhere inside my virtualenv (and thus outside of my version controlled repo). So I'm thinking ./manage.py syncdb is sufficient, no need to use South?

MonkeyMaker
May 22, 2006

What's your poison, sir?

fletcher posted:

Is it necessary to make a South migration for something like python-social-auth? If you just do a pip install python-social-auth and then ./manage.py schemamigration social.apps.django_app.default --initial, I think the migration file ends up somewhere inside my virtualenv (and thus outside of my version controlled repo). So I'm thinking ./manage.py syncdb is sufficient, no need to use South?

Don't make migrations for software you don't control.

Adbot
ADBOT LOVES YOU

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

MonkeyMaker posted:

Don't make migrations for software you don't control.

Ok cool, thanks!

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