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
Hed
Mar 31, 2004

Fun Shoe
Since pytest was brought up in the other thread, I wanted to see what I was missing here.

I get that just writing assert statements is more elegant than self.assertBlah() all over, but it looks like if I do Django tests that require DB access, I have to put decorators everywhere, and it doesn’t look nice to me. Am I missing something?

Nothing to do with pytest but looking at my testing more rigorously did give me the excuse to grok factoryboy and faker, though, so that has cleaned up my tests significantly. They are much easier to reason about now.

Adbot
ADBOT LOVES YOU

Thermopyle
Jul 1, 2003

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

Hed posted:

Since pytest was brought up in the other thread, I wanted to see what I was missing here.

I get that just writing assert statements is more elegant than self.assertBlah() all over, but it looks like if I do Django tests that require DB access, I have to put decorators everywhere, and it doesn’t look nice to me. Am I missing something?

Nothing to do with pytest but looking at my testing more rigorously did give me the excuse to grok factoryboy and faker, though, so that has cleaned up my tests significantly. They are much easier to reason about now.

Did you look at pytest-django?

Hed
Mar 31, 2004

Fun Shoe
I had it installed but was following the OG pytest docs. Now I'm off to the races, 100% natural testing with 20% less boilerplate. Thanks!

porksmash
Sep 30, 2008
I found a need to load a users session data because whatever was being loaded is what was causing a server error. Since nearly all the docs guide you to use the session in your views via the request object I thought it might come in handy to share how to get arbitrary session data within the Django shell and not have to hit up SQL or redis/memcached with their native query tools.

code:
>>> from importlib import import_module
>>> from django.conf import settings
>>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
>>> s = SessionStore()
>>> s._session_key = '<unique_session_key>'
>>> s.load()
{<the session data>}

a dingus
Mar 22, 2008

Rhetorical questions only
Fun Shoe
Not sure if this is a django specific question or more of a development one, but how do you all manage technical differences between your development and production setups?

For example, I am working on a personal blog using S3 to host static files. When I make a front-end change on my local development machine I have to push my new CSS file to S3 in order to see the changes on my django development server... this obviously sucks because I am pushing a chunk of changes to production each time I want to check out what I've done. Is there an easy way to get my development machine to pull static files locally? I know there must be I am a newbie.

For now I have been making changes in the developer console of Firefox and migrated them to my CSS and HTML files when I'm done.

minato
Jun 7, 2004

cutty cain't hang, say 7-up.
Taco Defender
I use WhiteNoise for local static files.

a dingus
Mar 22, 2008

Rhetorical questions only
Fun Shoe
I was using WhiteNoise before but switched to S3 because I thought it would be more efficient. Looking into it a little deeper I realized I actually want to:

Serve media files from S3 all of the time (at least for now).
Serve static files from Django or WhiteNoise in development only.

It looks like I can accomplish this by adding a simple if statement to my settings.py which I will try: https://testdriven.io/blog/storing-django-static-and-media-files-on-amazon-s3/

Thermopyle
Jul 1, 2003

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

a dingus posted:

I was using WhiteNoise before but switched to S3 because I thought it would be more efficient. Looking into it a little deeper I realized I actually want to:

Serve media files from S3 all of the time (at least for now).
Serve static files from Django or WhiteNoise in development only.

It looks like I can accomplish this by adding a simple if statement to my settings.py which I will try: https://testdriven.io/blog/storing-django-static-and-media-files-on-amazon-s3/

Did you read this?

http://whitenoise.evans.io/en/stable/#infrequently-asked-questions

duck monster
Dec 15, 2004

PT6A posted:

I'd say that goes beyond "very good idea" to "essentially malpractice to not do."

The fact a lot of platforms still seem stuck on 2.7 as the default python makes it pretty much a necessity.

Hed
Mar 31, 2004

Fun Shoe
I was going to build an app on to a project where users can design arbitrary questionnaires / polls. Since a dynamic schema can be a little tricky, has anyone used Entity-attribute-value package like django-eav2? I'm considering using that to store the data to tie back to a Django object.

Alternatively I could just use JSON(B) fields. Given that I want to run calculations and eventually report on these I'm trying to see if anyone has anything that worked well for them in the past.

susan b buffering
Nov 14, 2016

Why do you think you need a dynamic schema? What you described has a pretty natural database model and would be pretty bad in an eav table.

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled

Hed posted:

I was going to build an app on to a project where users can design arbitrary questionnaires / polls. Since a dynamic schema can be a little tricky, has anyone used Entity-attribute-value package like django-eav2? I'm considering using that to store the data to tie back to a Django object.

Alternatively I could just use JSON(B) fields. Given that I want to run calculations and eventually report on these I'm trying to see if anyone has anything that worked well for them in the past.
EAV is cool, and definitely has its uses, but it sounds like it may be overkill here. Consider that the official Django tutorial is a poll application too, and it doesn't use EAV or anything advanced like that.

Hed
Mar 31, 2004

Fun Shoe
Thanks guys, after thinking a bit more about it you’re both right. I was getting hung up on how people could dynamically assign questions to questionnaires and went looking for complicated solutions instead of back to fundamentals.

epswing
Nov 4, 2003

Soiled Meat
I've got an api endpoint that may return JsonResponse({'detail': 'Some error msg'}, status=400), and when it does, I see [2019-10-21 14:26:18] WARNING log Bad Request: /my/url/ in the logs. I do want to show warnings in my logs, but not every time I return a 400. I've looked at JsonResponse (and its superclasses, HttpResponse and HttpResponseBase) in the source for Django 2.2 and I can't find any spot that is explicitly logging the 400. The docs for requests/responses don't mention anything about logging either.

How/where can I tell Django to not log a 400 response as a warning?

Edit: Oh hey, the logging docs say "4XX responses are raised as WARNING messages" so, there you go.

epswing fucked around with this message at 20:45 on Oct 21, 2019

Thermopyle
Jul 1, 2003

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

epalm posted:

I've got an api endpoint that may return JsonResponse({'detail': 'Some error msg'}, status=400), and when it does, I see [2019-10-21 14:26:18] WARNING log Bad Request: /my/url/ in the logs. I do want to show warnings in my logs, but not every time I return a 400. I've looked at JsonResponse (and its superclasses, HttpResponse and HttpResponseBase) in the source for Django 2.2 and I can't find any spot that is explicitly logging the 400. The docs for requests/responses don't mention anything about logging either.

How/where can I tell Django to not log a 400 response as a warning?

Edit: Oh hey, the logging docs say "4XX responses are raised as WARNING messages" so, there you go.

Edit your logging config with a custom filter.

Data Graham
Dec 28, 2009

📈📊🍪😋



Django3 wooo!

Best thing for me right off the bat looks to be the queryset filtering based on bool-returning model properties. Seems like black magic but I’m giving it a test drive as soon as my power comes back on and I dig out from this snowbank

Dominoes
Sep 20, 2007

I love the new model enums; it's something I've wanted for a while. Gives you different varieties based on how you want it to be stored in the db, ie integer, char, or something else, then works like a normal enum in the Python code.

Migrating's easy, assuming you don't change how the data's represented in the DB.

Ie replace this:
Python code:
# choices
A = 0
B = 1
C = 2

class AModel(models.Model):
    CHOICES = (
        (A, "A"),
        (B, "B"),
        (C, "D"),
    )    
   val = models.IntegerField(default=A, choices=CHOICES)


#...
if my_model.val == models.A:
    pass
with:
Python code:
class Choice(models.IntegerChoices):
    A = 0  # Still explicitly define the integer value for frontend compatibility
    B = 1
    C = 2

class AModel(models.Model):
   val = models.IntegerField(default=Choice.A, choices=Choice.choices)

#...
if my_model.val == models.Choice.A:
    pass
There are probably other patterns compared to the first one I posted; I'd been using that since it was relatively clean, but involved unassigned module-level vars, which I don't like. It now feels like a proper enum.

Dominoes fucked around with this message at 03:59 on Dec 3, 2019

KICK BAMA KICK
Mar 2, 2009

So if I'm a coding novice in the middle of developing a Django 2 project (haven't deployed anything yet) that doesn't involve any particularly complex or out of the ordinary Django features: how much would probably break/how much would I gain from trying out Django 3? I do have pretty decent test coverage so I think I'd catch most of the broken stuff quickly.

e:

Dominoes posted:

I love the new model enums; it's something I've wanted for a while. Gives you different varieties based on how you want it to be stored in the db, ie integer, str, or something else, then works like a normal enum in the Python code.
Oh yeah that's something I would use right there.

Dominoes
Sep 20, 2007

The only thing that broke for me was having to replace { % load staticfiles %} with { % load static %}. Check out the list of removed features.

I finally was able to remove this comment from my models.py: # Choices listed here; Django should just support enums directly...

Thermopyle
Jul 1, 2003

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

KICK BAMA KICK posted:

So if I'm a coding novice in the middle of developing a Django 2 project (haven't deployed anything yet) that doesn't involve any particularly complex or out of the ordinary Django features: how much would probably break/how much would I gain from trying out Django 3? I do have pretty decent test coverage so I think I'd catch most of the broken stuff quickly.

e:

Oh yeah that's something I would use right there.

Django is really good about not majorly breaking stuff between versions, and they give good info about what you need to change,if anything.

Data Graham
Dec 28, 2009

📈📊🍪😋



Yeah, this isn't like Python2->3 (though my reptile brain did rebel briefly against me when I saw the announcement)

epswing
Nov 4, 2003

Soiled Meat
Can we talk about Class Based Views for a sec?

I understand the motivation behind CBV. If you kept iterating on how Django views work in a CRUD context, and kept automating away any duplicate/boilerplate code, I can see how you'd end up at CBV. But suddenly, How Things Work is now hidden behind a bunch of inherited classes, and because I haven't sat down and formally learned the ins/outs of each class, I have to constantly check the source to figure out how they work, which variable to set, what types they expect, the order in which all these functions get called, etc.

I get that they've built this nice efficient machine to get work done in the smallest possible amount of code, and I agree that's a Good Thing, but what they've lost is the simplicity of FBV. Here's the function, here's the Request, just do what you need and return a Response.

I know the right answer is for me to stop whining, buckle up, and just learn CBV, but what drew me to Django in the first place was it's simplicity, and I feel like the transition from FBV to CBV is an increase in complexity.

Anyone else feel this way?

Thermopyle
Jul 1, 2003

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

Everybody feels that way until they've buckled down and learned them and even then, what you say isn't wrong, it's just that CBV's bring real benefits in the right situations.

There's nothing wrong with just using FBV's, but you should buckle down and learn CBV's and use them enough to get the experience to know when they're a good fit to save you time and when they're not.

porksmash
Sep 30, 2008
https://ccbv.co.uk/ is a great helper for learning CBVs.

epswing
Nov 4, 2003

Soiled Meat

Thermopyle posted:

Everybody feels that way until they've buckled down and learned them and even then, what you say isn't wrong, it's just that CBV's bring real benefits in the right situations.

There's nothing wrong with just using FBV's, but you should buckle down and learn CBV's and use them enough to get the experience to know when they're a good fit to save you time and when they're not.

Yeah... agreed. CBV just feels like a heavy ASP.NET project now, where FBV are nimble, easy, and obvious.

porksmash posted:

https://ccbv.co.uk/ is a great helper for learning CBVs.

Oh cool, I've spent countless hours using the equivalent for DRF http://www.cdrf.co/ it's been a very helpful resource.

Dominoes
Sep 20, 2007

epalm posted:

Can we talk about Class Based Views for a sec?

I understand the motivation behind CBV. If you kept iterating on how Django views work in a CRUD context, and kept automating away any duplicate/boilerplate code, I can see how you'd end up at CBV. But suddenly, How Things Work is now hidden behind a bunch of inherited classes, and because I haven't sat down and formally learned the ins/outs of each class, I have to constantly check the source to figure out how they work, which variable to set, what types they expect, the order in which all these functions get called, etc.

I get that they've built this nice efficient machine to get work done in the smallest possible amount of code, and I agree that's a Good Thing, but what they've lost is the simplicity of FBV. Here's the function, here's the Request, just do what you need and return a Response.

I know the right answer is for me to stop whining, buckle up, and just learn CBV, but what drew me to Django in the first place was it's simplicity, and I feel like the transition from FBV to CBV is an increase in complexity.

Anyone else feel this way?
Never use them; no reason in particular, it's just that Django has a huge surface area, and you don't need it all to get things done. That said, I'm curious what I'd get out of them, since function views are quite elegant and minimal as they are.

Thermopyle
Jul 1, 2003

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

Dominoes posted:

That said, I'm curious what I'd get out of them

Kind of the same reason you'd use classes in any program. They can aid in organization, conceptualizing problems, and reusing functionality.

In Django, views are just callables that take a request and return a response. Since classes can be callables, it's not a big leap to realize that you might want to use OOP to organize, conceptualize, and DRY. This is just Python, you don't need Django to do anything special for you, you can just write a class, specify the dunder method __call__ and use it as a view.

First thing to note about what Django provides to make this better is that there's two concepts in Django that people kind of conflate. There's CBV's and there's generic CBV's.

Regular CBV's are basically something like:

Python code:
from django.views import View

class FooView(View):
    def get(self, request):
        # GET request stuff

    def post(self, request):
        # POST request stuff
Not really gaining much over an if/else block in a FBV...unless you have a DRY problem and then you can use inheritance or composition to fix that up.

Generic CBV's build on top of that and provide classes that implement a lot of common web stuff, like CRUD views. They're powerful and complicated. In addition to the official docs, CCBV is a great site for coming to terms with them.

Django provides CBV's that start you on this road and standardize the ways to do it. The thing about this is that it's only really useful in a couple of situations. One, if you have a lot of logic you'd like to share amongst views, and secondly if the generic CBV's map closely on to what you're doing.

My biggest current project that isn't a REST API has about 50 views and maybe 8 of them are using CBV's and 4 of those are generic CBV's. It's not a simple straight forward CRUD thing so not a lot of use for generic CBV's, and each view is pretty unique so not a lot of usage of regular CBV's.

Dominoes
Sep 20, 2007

Much appreciated. I think I need to read one of those tutorials and see where it would make the code cleaner.

Does anyone know how to handle CSRF tokens for forms? If I'm making a normal fetch request, I can pass the token as a header, after retrieving from document.cookie and doing some processing.

For using the <form /> approach, which I've been using for file downloads (There may be a way to download files with Fetch, but I'm struggling on that too), I've been using a React component, where you just insert this tag somewhere in your form: <DjangoCSRFToken />. How can I do form based approaches without the React module? I'm doing a non-react project, and want to download a file, but am struggling.

Edit: I think I solved it, by passing an input with type="hidden", name="csrfmiddlewaretoken", and value, the result of the document.cookie used in the first approach. Gleaned from the Github of that React helper page.

Dominoes fucked around with this message at 21:07 on Dec 3, 2019

Business
Feb 6, 2007

Can someone tell me if this design makes sense for something I want to add to my basic django project?

Users have texts they keep in the database. I'll have a user select a text in a form and then 'process' it (I keep this separate from the upload system in the case I later add something to have them 'process' it in a different way). There's no reason the 'processed' version needs to go in a database, but it does need to be saved somewhere on disk. Once it's saved, users can query the 'processed' version in different ways. The 'processed' version can get deleted at end of session, logout, whatever.
The things I'm stuck on, conceptually:
1. Can I do all this with FileSystemStorage()?
2. How would I use the query form to have a user select a processed file? My guess is that I would associate the file on disk to the model text that generated it, and have the user select it that way?
3. Is it common to just use session data to determine when I clear out the files even though I have user authentication? The files are small so it's not really a storage issue, I just assume I need some process for cleaning house.

Also if anyone can recall a book/tutorial that covers something similar in practice. Haven't been able to turn anything up this morning but could be because I'm not getting the right terms or something.

Ahz
Jun 17, 2001
PUT MY CART BACK? I'M BETTER THAN THAT AND YOU! WHERE IS MY BUTLER?!

Business posted:

Can someone tell me if this design makes sense for something I want to add to my basic django project?

Users have texts they keep in the database. I'll have a user select a text in a form and then 'process' it (I keep this separate from the upload system in the case I later add something to have them 'process' it in a different way). There's no reason the 'processed' version needs to go in a database, but it does need to be saved somewhere on disk. Once it's saved, users can query the 'processed' version in different ways. The 'processed' version can get deleted at end of session, logout, whatever.
The things I'm stuck on, conceptually:
1. Can I do all this with FileSystemStorage()?
2. How would I use the query form to have a user select a processed file? My guess is that I would associate the file on disk to the model text that generated it, and have the user select it that way?
3. Is it common to just use session data to determine when I clear out the files even though I have user authentication? The files are small so it's not really a storage issue, I just assume I need some process for cleaning house.

Also if anyone can recall a book/tutorial that covers something similar in practice. Haven't been able to turn anything up this morning but could be because I'm not getting the right terms or something.

Just keep it in the DB, or if it's not too big, in the session. Maybe go fancy with your session backend if you like, like Redis.

NtotheTC
Dec 31, 2007


I was gunna say- unless there's a reason you specifically need as a file on disk (i.e. you need to invoke a program in the background to parse the file?) I'd just keep the processed version cached in memory for the duration of the session.

NtotheTC fucked around with this message at 20:13 on Dec 6, 2019

punished milkman
Dec 5, 2018

would have won
Just googling around and seeing there are quite a few options for maintaining an audit trail of changes to records in Django. Does anyone here have a preferred solution? I'm interested in maintaining which fields were modified, including the old values, along with the user that did it with a timestamp.

Data Graham
Dec 28, 2009

📈📊🍪😋



We use https://github.com/treyhunner/django-simple-history at work. It does the job pretty well, but heaven help you if you have a model called "instance" (because it heavily uses that as a reserved internal term) :suicide:

punished milkman
Dec 5, 2018

would have won
Nice, that looks absolutely perfect. Thanks dude.

KICK BAMA KICK
Mar 2, 2009

How many more times am I gonna be trying to nest like three {% with some_str= [...] %} and a bunch of filters to get a template to display something formatted a certain way if a value exists but something else formatted different if it's not before I realize "just put a method on the model that handles it with a one-line f-string and call that from the template"?

I'm sure I'm just overlooking the right filters to more efficiently do what I want but I have a bad habit of trying to make like yesno and default_if_none handle situations more complex than they should.

CarForumPoster
Jun 26, 2013

⚡POWER⚡

KICK BAMA KICK posted:

How many more times am I gonna be trying to nest like three {% with some_str= [...] %} and a bunch of filters to get a template to display something formatted a certain way if a value exists but something else formatted different if it's not before I realize "just put a method on the model that handles it with a one-line f-string and call that from the template"?

I'm sure I'm just overlooking the right filters to more efficiently do what I want but I have a bad habit of trying to make like yesno and default_if_none handle situations more complex than they should.

f-strings are the best things

Hed
Mar 31, 2004

Fun Shoe
What's a good basic blog app to use on a project in 2020? I see from django-packages mezzanine is still around but feels kind of heavyweight. I really just need basic formatting with image insertion, posts, tags, and permalinks.

NtotheTC
Dec 31, 2007


Zinnia was good in the past, looks like it hasn't been updated recently though.

There are a couple of Wagtail blog apps but that's probably too heavyweight as well. If it's really basic blog functionality you need then implementing it yourself is possibly the most lightweight way of doing it

E; Wagtail is cool and good by the way

Thermopyle
Jul 1, 2003

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

Every time I've wanted a lightweight blog app it just ended up being easier to implement it myself.

Adbot
ADBOT LOVES YOU

The Fool
Oct 16, 2003


Lightweight blogs are probably done best with a static site generator

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