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
Sock on a Fish
Jul 17, 2004

What if that thing I said?
Is there any good reason why I shouldn't customize a set of Users by creating them as instances of a subclass of django.contrib.auth.models.User? I can't see why it wouldn't, but the official book doesn't even suggest it as an idea, and further suggests that to create Users with a profile you should create a new model for the profile with the user id as a foreign key.

Adbot
ADBOT LOVES YOU

Sock on a Fish
Jul 17, 2004

What if that thing I said?

Bonus posted:

Because then you don't get to use some the nifty features that contrib.auth offers, like messages and getting the user directly from request. The proper way to extend the User model is described here.

Excellent, thanks!

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I've Googled around, and can't find an answer -- is there any significant performance boost from using a SmallIntegerField in my models instead of an IntegerField? One of my models is going to have about 100 attributes, only a handful of which are going to be negative or possibly exceed 65,535. However, I'd rather not make my model less flexible unless I'm going to get something for it.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
Say I want to weigh the items returned in a search based on what other users have selected for the same search. Should I create a new model and new record for every search? Should I add a dict to the model on the items being searched? Is there an easy way to serialize a dict and put it in the database?

It seems like storing a record of every search made would eventually take up huge amounts of space, but at the same time it seems almost inappropriate to store this data in the model for the items being searched.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

No Safe Word posted:

How fuzzy is it going to be? Are you only interested in exact search string matches? Or stuff that "kinda looks like it"? It might be something that you just pick a solution and run with it for a while to see if you hit a wall. My gut tells me it should be a separate model, but I'm having a tough time coming up with the best structure for it.

Exact strings matches would be best. It's a pretty focused tool, where people are going to make lots of the same queries over and over again. I'm also toying with the idea of not only weighting based input from the entire userbase, but individual users, as well. If I go with a separate model, I'd just need to add a single attribute to the model.

The tag-like structure was the other option I was considering, but after more thought I think a separate model would be best. Something like:
code:
class Item(Models.model):
   attr1 = Models.CharField(max_length=60)
   ...

class ItemQuery(Models.model):
   item = Models.ForeignKey(Item)
   query = Models.CharField(max_length=60)
   user = Models.ForeignKey(User)
Then I'd have either a system of methods or some logic in my views that weights things appropriately when ordering search results.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I'm trying to use a ModelChoice field in one of my forms and I need to use a variable in my queryset arg that I'd pass to the form init in a view.

I was struggling with this last night and am still struggling with it today. It looks like **kwargs are out unless I start mucking about with Django internals, they're available for the field init but not the form init. It looks like neither the form or field class has any knowledge of the request.

How do I do this? There's got to be a way, the ModelChoice field is going to be fairly useless if you can't use variables in your queryset filters.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

nbv4 posted:

you can add in a new form init argument and then call super(). Heres a snippet of some of my code where I do this:

code:
class FlightForm(ModelForm):
    def __init__(self, *args, **kwargs):  
        super(FlightForm, self).__init__(*args, **kwargs)
        
        from share.middleware import share
        from django.db.models import Max
        self.fields['date'].widget = widgets.AdminDateWidget()
        self.fields['plane'].queryset = \
                    Plane.objects\
                    .user_common(share.get_display_user())\
                    .annotate(fd=Max('flight__date')).order_by('-fd')
        self.fields['plane'].default=1
        self.fields['plane'].blank=False
        self.fields['plane'].null=False

I've done this:
code:
class EventRegForm(forms.Form):
	def __init__(self, *args, **kwargs):  
		super(EventRegForm, self).__init__(*args, **kwargs)
		self.event_id = kwargs['event_id']
	meal_choice = forms.ModelChoiceField(queryset=EventMealChoice.objects.filter(event__id=self.event_id),required=False)
	stay_at_hotel = forms.BooleanField(label='stay at hotel?',required=False)
	confirm_reg = forms.BooleanField(label='confirm registration')
But I'm now being told that 'self' is not defined on the line where I initialize meal_choice.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

king_kilr posted:

pop event_id out *before* you call super().

You're both right! Thanks!

Sock on a Fish
Jul 17, 2004

What if that thing I said?

SlightlyMadman posted:

Do I have to do something special to call a custom function of a method from a template? I have a class like this:

code:
class Purchase(models.Model):
    ...
    def get_price(self):
        price = 0
        for ticket in self.ticket_set:
            price += ticket.tier.price
        return price
and a method like:

code:
{% for purchase in purchases %}
    <br/>Total Price: {{ purchase.get_price }}
{% endfor %}
It iterates the purchase just fine (I'm actually printing other information in my real code so I see it), but the purchase.get_price reference doesn't return anything, not even the "0" it would return if self.ticket_set were empty.

The templating language doesn't supporting calling methods. Call it in your view and assign its output to a variable that you'll pass to the template.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
What's your preferred way of handling payments? I've looked at PayPal, Google Checkout, and Amazon FPS and none of them official Python libraries. The third-party libraries I've found don't look very well maintained. Do most people resort to manually crafting JSON and SOAP requests for these services?

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I've been having good luck with django-paypal. It has a few forks, this one seems to work best. It comes with forms that you can use to generate buttons to send users over to PayPal to make their payment, as well as a form to handle the POST from PayPal that they use to indicate payment success.

It looks like you'll need a pro account to avoid sending users offsite, but that's okay for my requirements.

Googling 'paypal python' didn't turn that up in the first few pages of results, I had to search for 'django paypal' to find it.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I'm trying to deploy with WSGI and am apparently an idiot. I've got a test WSGI script that will return an HTTP response just fine, but when I try to access my app I get 403'd. I've verified that filesystem perms are appropriate, and have verified that I can run the dev server on the production platform just in case some dependency was missing. When I call my Django WSGI on the command line it runs and exits clean after a couple of seconds.

I think there must be something wrong with my Apache config. Here it is:
code:
<VirtualHost *:80>
ServerName somedomain.org

ErrorLog /var/log/httpd/somedomain.org-error_log
CustomLog /var/log/httpd/somedomain.org-access_log common


Alias /m /home/django/apps/myapp/r/

WSGIScriptAlias / /home/django/apps/myapp/apache/myapp.wsgi
WSGIDaemonProcess django processes=7 threads=1 display-name=django
WSGIProcessGroup django
WSGIApplicationGroup django

ErrorDocument 401 "Authentication Error"
ErrorDocument 403 "Forbidden"

<Directory /home/django/apps/myapp/apache>
   Order deny,allow
   Allow from all
</Directory>

<Directory /home/django/apps/myapp/r>
   Order deny,allow
   Allow from all
</Directory>

</VirtualHost>
I've tried commenting out the ErrorDocument directives to get better insight, I just get told by Apache that I don't have permissions to access whatever URL it is I'm trying to retrieve.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

Sock on a Fish posted:


I got this working, but I'm not sure why it was broken. I moved the app out of the /home/django dir and all is now well. Perms were set 644/755 for everything in my app's directory.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

bmoyles posted:

What are perms of the myapp and the /home/django directory? Many distros, when you create users, remove execute or read permissions on home directories. If /home/django was missing +x or /home/django/myapp was missing +x, the apache user wouldn't be able to change into that directory.

Ah, that probably would've been it then. I didn't think it mattered what the permissions of a directory many levels above my WSGI script were.

Entry in error log was simply:
code:
[Sun Dec 27 12:34:20 2009] [error] [client 4.4.4.4] (13)Permission denied: access to / denied
In access log:
code:
4.4.4.4 - - [27/Dec/2009:12:49:22 -0800] "GET / HTTP/1.1" 403 282

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I'd love to read more about the environment they're running in. Looks like nginx is their public-facing web server.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
Is anyone familiar with initial_data? I've reviewed the docs on it and it seems straightforward enough, but I can't get it to work.

I've got a file called initial_data.yaml, it looks like this:
code:
- model: django.contrib.auth.models.Group
  pk: 1
  fields:
    name: app_admin
    
- model: django.contrib.auth.models.Group
  pk: 2
  fields:
    name: services
I've tried placing it by itself in the root of the project, the root of the app, in a 'fixtures' folder in the root of the project and the root of the app, but so far nothing has gotten recognized by a syncdb command. The only thing I can think of is that the django.contrib.auth.models.Group model isn't supported as a fixture, but I just can't believe that could be real, there are so many testing scenarios where you'd want to verify that someone has some quality before proceeding to perform some action.

Where am I going wrong?

Sock on a Fish
Jul 17, 2004

What if that thing I said?

Sock on a Fish posted:


Figured it out, Django doesn't even try to deserialize YAML if PyYAML isn't installed. Installed PyYAML, got another error about invalid model name, used dumpdata to find that the actual name is 'auth.group', and now everything works proper.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
Does anyone use fabric?

I'm trying to get fabric, in one operation, to selectively apply certain sub-operations only to a subset of hosts. e.g., when deploying I want to copy new files to all application servers, but I only want to syncdb, do a south migration, and install some cron jobs on one host.

I tried to accomplish this by defining two roles, one 'primary_host' that updates the db and has cron jobs, and another 'whole_cluster' that consists of every app server. I've got one function that's decorated with an @roles('primary_host') that contains calls to a bunch of other functions, some which are decorated the same and some which are decorated @roles('whole_cluster').

The problem is, when I run that one big function, the actions are only performed on the primary_host. Am I doing this wrong, or is this a limitation of fabric? Right now it seems like I'm going to have to write a shell script that calls fabric with different host arguments.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
Eh, wasn't that bad, I'd still like to keep it all in Fabric if that's what I'm using anyway:

code:
#!/bin/bash

fab enable_maintenance_mode --roles=whole_cluster

# turn on maintenance mode in settings.py in current working directory
sed -r -e 's/MAINTENANCE_MODE = False/MAINTENANCE_MODE = True/g' settings.py

fab update_application_files --roles=whole_cluster

fab update_primary_host --roles=primary_host

fab disable_maintenance_mode --roles=whole_cluster

Sock on a Fish
Jul 17, 2004

What if that thing I said?

bitprophet posted:

Hope that makes some sense.

Perfect sense, thanks. That reminds me of figuring out that the cd() context manager doesn't process absolute paths correctly, so before every cd('/some/abs/path') I'd have to set env.cwd to ''.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

bitprophet posted:

Hmm. That should only be the case if env.cwd is set to a non-empty value beforehand, such as if you were to call cd within another cd block. Can you verify whether that's what's going on?

Edit: If we have to do more than another back-and-forth on this, given it's not that Django related, maybe I should make a Fabric thread. Then again I can't imagine that many goons use it, so maybe we should just take it to email or PM.

Oh yeah, it was a cd within a cd. I had some functions that were executing other functions within a cd context, and within those functions themselves there was a cd context specified as well. That really threw me, I assumed that any path starting with '/' would be interpreted as absolute.

Sock on a Fish
Jul 17, 2004

What if that thing I said?
Does anyone have insight on keeping their Django code readable and testable? I read through Clean Code a couple of months back and have been trying to keep from letting my code get bloated and too multi-purposed, but it's not readily apparent what the best way to do that is in Django.

I've started to define functions within my view functions to better separate layers of abstraction while keeping everything logically grouped together as a single unit, but I can't figure out how to use those from outside of the function, which means I can't write tests for them.

Is the only way to just have a whole bunch of functions in the same namespace as your view function? Maybe define each view and associated functions within a discrete Python file?

It seems like it'd be easier if every view was a class instead of a function.

Sock on a Fish
Jul 17, 2004

What if that thing I said?

MonkeyMaker posted:

So write class-based views? http://lmgtfy.com/?q=class-based+views+django

Is that what most people do? It doesn't have to be class-based, and honestly reading through those results class-based views look like a kludgy hack that could possibly be broken in later Django releases.

edit: I'm thinking it might make more sense to make a views folder, and then for each view or set of closely related views a separate file.

Sock on a Fish fucked around with this message at 21:08 on Jun 3, 2010

Adbot
ADBOT LOVES YOU

Sock on a Fish
Jul 17, 2004

What if that thing I said?
I'm repeating myself in some form validation code for separate forms that use some of the exact same fields.

Is the accepted way to solve this problem to define the validation function outside of the forms, have the clean_field_x() function in the form class do nothing, then override __init__ and after calling the superclasse's __init__ assign self.clean_field_x to the shared validation function?

Is there a better way?

edit: duh, define clean_field_x in a superclass

Sock on a Fish fucked around with this message at 18:02 on Oct 4, 2010

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