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
ashgromnies
Jun 19, 2004
This post makes me want to learn Django... anyone know of a good cheap webhost that supports using it?


edit: oh, this place looks solid http://www.webfaction.com/services/hosting

anyone have experience?

ashgromnies fucked around with this message at 20:22 on Mar 7, 2008

Adbot
ADBOT LOVES YOU

ashgromnies
Jun 19, 2004

SmirkingJack posted:

If it is just for learning purposes then I always vote for a local virtual machine. Install VMware Server (free) and slap your favorite *nix OS (free) and set it up. If you already know what you are doing then it's a breeze, if you don't then it will give you good knowledge of how a web server works that will be valuable later on. The ability to take snapshots of your system and roll it back if you royally screw something up is also really nice.

Nah, I want to write my personal site to run on a Django backend so other people can view it...

http://www.webfaction.com/services/hosting looks like they have what I want, but I don't know if I could set up some sort of version control system on there.

edit: oooh One-click webdav and subversion repositories (over SSL)
this is getting a little off-topic though but they look like they'd be a good Django webhost :)

ashgromnies fucked around with this message at 20:34 on Mar 7, 2008

ashgromnies
Jun 19, 2004

Bonus posted:

How about going with a VPS? I hear slicehost are really good and also I think legalcondom is offering good and cheap VPS hosting for gunes.

Slicehost costs more than I'd like to pay for, though... I can get Webfaction hosting with ssh and svn and all sorts of fun stuff for like $70 a year versus $240/yr for Slicehost... considering my site is just personal and won't have any advertising or anything on it to make money I want a cheap solution :)

ashgromnies
Jun 19, 2004
I think I'm doing something wrong... I just started with Django and got everything set up and got the administrative interface working.

My Project is named "mysite" and my App is "blog". I opened up czubus/settings.py and added "blog" to the INSTALLED_APPS array, but now I get an error:

ImproperlyConfigured: Error importing middleware django.contrib.sessions.middleware: "No module named blog"

It makes me think it's in the wrong namespace or a path is misconfigured somewhere, but I don't know where to start looking.

edit: Ahah, got it... turns out I was right - it was in the wrong namespace, so I had to put "mysite.blog" instead of just "blog" in the INSTALLED_APPS. You might want to change that in the tutorial :)

ashgromnies
Jun 19, 2004

Bonus posted:

What does your directory and file layout look like? Because adding just app_name to INSTALLED_APPS wihtout prefixing it with the site name should work, at least it works for me.

code:
`-- mysite
    |-- __init__.py
    |-- __init__.pyc
    |-- blog
    |   |-- __init__.py
    |   |-- __init__.pyc
    |   |-- models.py
    |   |-- models.pyc
    |   |-- urls.py
    |   |-- urls.pyc
    |   |-- views.py
    |   `-- views.pyc
    |-- manage.py
    |-- settings.py
    |-- settings.pyc
    |-- urls.py
    `-- urls.pyc
Okay guys I am having another issue, syncdb isn't syncing the database like it should. I changed the BlogPost model to look like this:


code:
class BlogPost(models.Model):
    Title       = models.CharField(maxlength=255)
    Category    = models.ForeignKey(Category)
    Slug        = models.SlugField(prepopulate_from=('Title',))
    Author      = models.ForeignKey(User)
    PostText    = models.TextField()
    PublishDate = models.DateTimeField(auto_now_add=True)
    Featured    = models.BooleanField(default=False,help_text='Display this post on the featured area on the front page')

    def __str__(self):
        return self.Title
    class Admin:
        search_fields = ['Title', 'PostText','Category',]
        list_display = ['Title', 'Category', 'Author', 'PublishDate','Featured']
        list_filter = ['Category', 'Author', 'PublishDate','Featured']
        fields = (
            ('Details', {'fields': ('Slug','Author','PublishDate',), 'classes': 'collapse'}),
            (None, {'fields': ('Title','Category','Featured','PostText',)})
        )
    class Meta:
        pass

then ran python mysite/manage.py syncdb
code:
~/webapps/django>sdb
Loading 'initial_data' fixtures...
No fixtures found.
and then when I try accessing the admin page...
(1054, "Unknown column 'blog_blogpost.Featured' in 'field list'")

What do I need to do to get it to really sync and add that column to the table?


edit: oh, the docs!

code:
syncdb will only create tables for models which have not yet been installed. It will never issue ALTER TABLE statements to match changes made to a model class after installation.
durr

ashgromnies
Jun 19, 2004

ATLbeer posted:

Yeah.. Thats a knock for Django right now. Especially during rapidly changing developments. It's hard to alter schemas quickly and efficiently.

It's currently an open issue in the dev group of the Django Project - http://code.djangoproject.com/wiki/SchemaEvolution

There also is some community code contribution that helps this out a bit as well - http://code.google.com/p/django-evolution/

Ah, okay, I see. I updated my version of Django to the svn-trunk version(my hosting company gave me 0.96) and grabbed django-evolution from their repository and everything seems to work awesome now. Thanks!

Okay, now I have a weird issue with the way Django is escaping my output, I think... it didn't happen when I was running 0.96 but basically I put TinyMCE on my admin page so that I had a WYSIWYG editor for my blog posts, and it stores to the database fine, but then when I print it to the template...

code:
[b]View:[/b]
def index(request):
    featured_blog_post = BlogPost.objects.filter(Featured=True).order_by('-PublishDate')[0]
    t = loader.get_template('blog/index.html')
    c = Context({
        'featured_blog_post': featured_blog_post,
    })
    return HttpResponse(t.render(c))


[b]Template:[/b]
{% if featured_blog_post %}
<div id="featured_blog">
    <h2>Recent Blog Post<img src="/media/img/blog/brownpelican.png" alt="an adorable brown pelican"/></h2>
        <div class="post">
        <h2>{{ featured_blog_post.Title }}</h2>
        <h3>{{ featured_blog_post.PublishDate }}</h3>
        {{ featured_blog_post.PostText }}
    </div>
</div>
{% endif %}
The HTML inside the PostText doesn't get processed by the browser, it gets printed out as plain text.

For reference, here's the HTML inside the PostText...

code:
<p>hello world! <a href="http://www.google.com" target="_blank">here</a> you <strong>will see</strong> neat things. <span style="text-decoration: underline;">maybe!</span></p>

ashgromnies
Jun 19, 2004

deimos posted:

After .96 all html gets escaped, you need to disable auto-escaping.
See here.

That's the ticket! Thanks a lot.

Now to write my own custom version of the truncatewords_html filter to create a link to the full article based on its slug... I'm underway! :)

ashgromnies
Jun 19, 2004
I've stumbled across a weird bug in Django that I can't reproduce reliably. It appears to be an error with the way it's handling regular expressions or something.

Occasionally when I enter the path http://mysite.com/admin, it redirects me to a "cannot load view page" for the view "article_detail" which is linked to in the mysite.blog urls, so I don't know how it can ever touch it.

code:
[b]mysite/urls.py[/b]
from django.conf.urls.defaults import *
from mysite.blog.urls import *

urlpatterns = patterns('',
     (r'^admin/?', include('django.contrib.admin.urls')),
     (r'^articles/', include('mysite.blog.urls')), # articles
     (r'^', include('mysite.blog.urls')), # default
)


[b]mysite/blog/urls.py[/b]
from django.conf.urls.defaults import *

urlpatterns = patterns('mysite.blog.views',
    (r'^2003/$', 'special_case_2003'),
    (r'^(\d{4})/$', 'year_archive'),
    (r'^(\d{4})/(\d{2})/$', 'month_archive'),
    (r'^(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
    (r'^', 'index') # default
)
What's weird is that is happens maybe three times every 20 tries to access /admin. I made sure that I killed all the old Django instances and restarted fresh and it still occurred.

ashgromnies fucked around with this message at 05:13 on Mar 12, 2008

ashgromnies
Jun 19, 2004

king_kilr posted:

There shouldn't be a question mark after the '/' in admin.

Why not? I want the question mark to be optional. In most regular expression engines(including Python's), the question mark means to match the preceding character zero or one times.

ashgromnies
Jun 19, 2004
Thanks, fellas.

I'm learning Python as I do this as well, so it's a constant struggle :)

edit: nvm i'm dumb i didn't realize the node parser part was necessary and handled wayyy deep down

ashgromnies fucked around with this message at 18:26 on Mar 12, 2008

ashgromnies
Jun 19, 2004

ATLbeer posted:

I dunno if you posted in the right thread or not but, I'm a bit confused at what your trying to do there

"50" itself is a string. There's no reason to cast it into a string str("50") again.
- "50" == str("50") == True

To cast the string "50" into an integer (as you said 'Take 50 out of quotes') you would just int("50") the str part is redundant.

Yeah that wasn't even necessary. The problem was deeper down. Anyways, I have permalinks and an auto-summarize and link to full article tag now... neato!

code:
[b]models.py[/b]
class BlogPost(models.Model):
    Title       = models.CharField(max_length=255)
    Category    = models.ForeignKey(Category)
    slug        = models.SlugField(prepopulate_from=('Title',))
    Author      = models.ForeignKey(User)
    PostText    = models.TextField()
    PublishDate = models.DateTimeField(auto_now_add=True)
    Featured    = models.BooleanField(default=False,help_text='Display this post on the featured area on the front page')

    def __unicode__(self):
        return self.Title
    class Admin:
        search_fields = ['Title', 'PostText','Category',]
        list_display = ['Title', 'Category', 'Author', 'PublishDate','Featured']
        list_filter = ['Category', 'Author', 'PublishDate','Featured']
        fields = (
            ('Details', {'fields': ('slug','Author','PublishDate',), 'classes': 'collapse'}),
            (None, {'fields': ('Title','Category','Featured','PostText',)})
        )
        js = ('/media/js/tiny_mce/tiny_mce.js','/media/js/admin/textareas.js')
    class Meta:
        pass
    def get_absolute_url(self):
        y = str(self.PublishDate.year)
        m = str(self.PublishDate.month).zfill(2)
        d = str(self.PublishDate.day).zfill(2)
        s = str(self.slug)
        return ('django.views.generic.date_based.object_detail', (), {'year': y, 'month': m, 'day': d, 'slug': s})
    get_absolute_url = permalink(get_absolute_url)
code:
[b]urls.py[/b]
info_dict = {
    'queryset': BlogPost.objects.all(),
    'date_field': 'PublishDate',
    'month_format': '%m',
}

urlpatterns = patterns('',
    (r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$', 'django.views.generic.date_based.object_detail', info_dict),
    (r'^archive$', 'django.views.generic.date_based.archive_index', info_dict),
    (r'^$', 'czubus.blog.views.index') # default
)
code:
[b]templatetags/tags.py[/b]
register = template.Library()
@register.tag(name='truncate_linkify')
def do_truncate_linkify(parser, token):
    """
    Truncates HTML after a certain number of words and
    makes the last word a link to the full article

    Argument: Number of words to truncate after.
    """
    try:
        arglist = token.split_contents()
        tag_name = arglist[0]
        value = arglist[1]
        length = arglist[2]
        link = arglist[3]
    except ValueError:
        raise template.TemplateSyntaxError, "tag requires exactly three arguments, got %r \nOR the value supplied for length was non-numeric" % token.contents.split()
    return FormatLinkifyNode(value,length,link)

from django.template import resolve_variable
class FormatLinkifyNode(template.Node):
    def __init__(self, value, length, link):
        self.value = value
        self.length = length
        self.link = link

    def render(self, context):
        from django.utils.text import truncate_html_words
        try:
            actual_value = resolve_variable(self.value, context)
            actual_link = resolve_variable(self.link, context)
            return re.sub(r'(.*)(\.{3})', r'\g<1><a href="'+actual_link+'">\g<2>(view rest of post)</a>', truncate_html_words(actual_value, self.length))
        except template.VariableDoesNotExist:
            return ''
code:
[b]index.html[/b]
{% truncate_linkify featured_blog_post.PostText 50 featured_blog_post.get_absolute_url %}
I'll probably make a writeup about this as soon as I clean up my code :)

The exception handling in tags.py is particularly stupid

ashgromnies
Jun 19, 2004

Nolgthorn posted:

What are you going to do in order to ensure that two of the same slugs aren't generated on the same day?

Make them unique in the model, I suppose.

slug = models.SlugField(prepopulate_from=('Title',),unique=True)


However that means that the same slug can only be used once for the entire life of the application and removes the purpose of going YYYY/MM/DD/slug

I will have to think about this. I'm at work right now and can't put too much thought into it, but that's a good consideration. I need to learn more about what functionality Django models offer me.

Is there a way to make a composite key across DatePublished/Slug?

edit: haiii
http://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys



Hmm. Since multiple-column primary keys aren't allowed, it seems like I could override the save method of the BlogPost model to verify that no post exists on that day with that slug before saving and otherwise throw an exception.

ashgromnies fucked around with this message at 17:06 on Mar 13, 2008

ashgromnies
Jun 19, 2004

Bonus posted:

Putting a Meta inner class inside a model and assigning unique_together fields effectively achieves the same thing as composite primary keys. They're not composite primary keys in the DB, but there's an index over both of them, so effectively it's the same.

But how can I do that since the PublishDate is a DateTimeField and I only want to compare the day, month and year and not the time?

ashgromnies
Jun 19, 2004

greenskeleton posted:

http://www.djangoproject.com/documentation/model-api/#unique-for-date

Would that be what you're looking for?

Uhm, yes, precisely. Wow, Django is awesome. I need to reread the docs.

It's not working for me though.

I have the latest version of Django, yes.


code:
class BlogPost(models.Model):
    Title       = models.CharField(max_length=255)
    Category    = models.ForeignKey(Category)
    slug        = models.SlugField(prepopulate_from=('Title',),unique_for_date="PublishDate")
    Author      = models.ForeignKey(User)
    PostText    = models.TextField()
    PublishDate = models.DateField(auto_now_add=True)
    Featured    = models.BooleanField(default=False,help_text='Display this post on the featured area on the front page')

    def __unicode__(self):
        return self.Title
    class Admin:
        search_fields = ['Title', 'PostText','Category',]
        list_display = ['Title', 'Category', 'Author', 'PublishDate','Featured']
        list_filter = ['Category', 'Author', 'PublishDate','Featured']
        fields = (
            ('Details', {'fields': ('slug','Author','PublishDate',), 'classes': 'collapse'}),
            (None, {'fields': ('Title','Category','Featured','PostText',)})
        )
        js = ('/media/js/tiny_mce/tiny_mce.js','/media/js/admin/textareas.js')
    class Meta:
        unique_together=(('PublishDate','slug'),)
    def get_absolute_url(self):
        y = str(self.PublishDate.year)
        m = str(self.PublishDate.month).zfill(2)
        d = str(self.PublishDate.day).zfill(2)
        s = str(self.slug)
        return ('django.views.generic.date_based.object_detail', (), {'year': y, 'month': m, 'day': d, 'slug': s})
    get_absolute_url = permalink(get_absolute_url)
I dropped the table and resynced because I couldn't get the evolution thing to actually perform any evolutions... whenever something changed it'd give me an error or warning.

I created a blog post through the admin interface with slug="test-post" then created a second one with slug="test-post" and they're both in there.

ashgromnies fucked around with this message at 19:00 on Mar 13, 2008

ashgromnies
Jun 19, 2004

FrontLine posted:

I have a Pythong script, separate from Django, that does a bunch of stuff to the image the user uploads. The specifics of what the script does isn't important. What I'd like to be able to do is have Django pass the file to my other script and have it kick off from there. The results are returned as 'results.xml' which are then formatted and displayed on the next webpage.

I have something similar, since I wrote a raw python script to be an API to twitter.com that I call in my Django application.

From what I understand, what Django calls a view is what is in most other frameworks the controller, at least from my experience in Catalyst and reading up on MVC. Django changed the names and went with Model-Template-View, which is a little weirder in my opinion, but it basically promotes thin model, thick view.

So what I did was abstracted everything in my script into a class and put it in my /usr/lib/python2.5/ directory(and added it to source control). Then, in my views.py I simply import that class, create a new instance of it, call the methods on it I need to get my output, and stash the results in the context and render a template.

I don't know if I'm doing it the "Django way" though, but it works for me and has the benefit of letting me use this API in non-Django python applications. I'm interested if there's another way I'm supposed to do this.

If you don't understand what I meant by this, I can give you code samples and an explanation more tailored towards your solution, but you should be able to see how you could adapt it to solve your problem.

ashgromnies
Jun 19, 2004
I'm kind of confused as to why you're handling it like that - why don't you force your views.py to use a different content-type and print the output directly to the browser depending on what they chose?

I know in the Catalyst framework for perl you can do this very easily, so that every view gets routed through an "end" method where you can check parameters(i.e. check which view they requested - html, json, xml, plaintext, etc.) and output the data depending on that.

I'd assume there's an easy way to make a generic method like that in Django but I haven't investigated.


EDIT: You know what... I love Django and the philosophy behind it but it's just not giving me what I need for development. I like working on things on the fly and implementing new features incrementally and Django offers no way to do that.

Sure, there's django-evolutions but I haven't gotten it to actually modify my tables - it always gives some cryptic error and I don't particularly feel like diving into it so I always end up wiping my database and resyncing.

I think I'm going back to Catalyst until Django gets a little bit more ready. I understand it's still not 1.0 yet, but the fact that you can't modify a model after it's been installed is a major sticking point for me.

ashgromnies fucked around with this message at 21:32 on Mar 24, 2008

ashgromnies
Jun 19, 2004

bitprophet posted:

I'm guessing you're not that great at SQL? I don't mean that in a mean sense - just that anyone who's intermediate with SQL would think absolutely nothing of 1) add or modify Django model field, 2) Execute a couple of ALTER TABLE statements or drop/create db and syncdb, 3) reload Apache, 4) test out new feature.

Having automagic schema evolution would be great, obviously, but doing it by hand is not difficult.

So I guess I just take issue with you claiming Django has "no way to implement features incrementally" - that's hogwash, I and thousands of others do it daily. It just doesn't go the extra mile to insulate people from having to know their database, and if that's something that you value, that's cool (again, I think Django should have the option to generate SQL updates) - just please don't frame it as the framework lacking something integral to Web development, which it does not.

I am very good with SQL, actually, I've been doing it for years - I just think that the framework should manage that for you. It seems like manually going into the database and altering the tables that it created for you goes against the idea and philosophy of the framework.

I also don't like the lack of a good DRY philosophy by implementing some sort of pre- and post-request methods for views. Maybe the functionality exists and I just haven't discovered it, but here's an example of a sticking point: Developing a RESTful Django application.

http://code.google.com/p/django-rest-interface/ is the implementation I'm going by.

This requires you to make a change for each model you have in order to make it exposed to be accessible in a RESTful manner. You need to alter both the model and the urls file.

code:
Step 4: For every model you want to be part of the API, create a Collection instance in urls.py (see more elaborate examples):

mymodel_resource = Collection(
    queryset = MyModel.objects.all(),
    responder = XMLResponder()
)
Couldn't that be genericized as to provide a much easier way to do this, then on the view post-processing redirect the user to whichever format of view they requested, rather than requiring the developer to specify a REST url for each file format for each model - once you have 4 different file formats and 5 models you want to expose, things start getting tedious.

ashgromnies fucked around with this message at 18:47 on Mar 25, 2008

ashgromnies
Jun 19, 2004

WickedMetalHead posted:

Couldn't you use Middleware to do this?

Not sure, I haven't looked at Middleware yet.

ashgromnies
Jun 19, 2004
Does anyone know anything about the ImageField that they tossed into the trunk version of Django? I can't find much documentation on it. I need to make sure the image a user uploads isn't some 100mb monstrosity and I can't really find anything on Google that helps me out. Anyone have any ideas?


edit: well, here are the two models I came up with. I think someone can still attack me just by virtue of uploading a huge image, though.

code:
from django.db import models
from django import newforms as forms
import Image, ImageFile

class ImageSizeLimitedField(forms.ImageField):
    def clean(self, value, initial):
        if not value:
            raise forms.ValidationError('Please upload an image')
        size = len(value['content'])
        if size > 1024000:
            raise forms.ValidationError('Filesize too large. Expected <= 1 megabyte')
        try:
            p = ImageFile.Parser()
            p.feed((value['content']))
            im = p.close()
        except IOError:
            raise forms.ValidationError('Please upload a valid image')
        return value

class ImageUploadForm(forms.Form):
    image = ImageSizeLimitedField()

ashgromnies fucked around with this message at 19:47 on Jun 2, 2008

ashgromnies
Jun 19, 2004
I'm having trouble tying my image to a model. Actually I don't even need a model for it quite yet because it's fine for me to discard the image after I am done with it, but I'd still like to be able to keep track of what goes on.

I'm following the examples at http://www.djangoproject.com/documentation/models/model_forms/

code:
from django.db import models
from django import newforms as forms
import Image, ImageFile
from django.newforms.models import ModelForm


class ImageSizeLimitedField(forms.ImageField):
    def clean(self, value, initial):
        if not value:
            raise forms.ValidationError('Please upload an image')
        size = len(value['content'])
        if size > 1024000:
            raise forms.ValidationError('Filesize too large. Expected <= 1 megabyte')
        try:
            p = ImageFile.Parser()
            p.feed((value['content']))
            im = p.close()
        except IOError:
            raise forms.ValidationError('Please upload a valid image')
        return value

class ImageUploadForm(models.Model):
    #image = forms.ImageField(upload_to="/some/path")
    image = ImageSizeLimitedField(help_text='Image to upload', upload_to="uploads/%Y%m%d%M")

class ImageUploadForm(ModelForm):
    class Meta:
        model = ImageUpload
Then when I try to print an instance of my form in a template, it doesn't work.

code:
views.py:

def index(request):
    contextDict = {}
    form = ImageUploadForm()
    contextDict['UploadForm'] = form
    c = Context(contextDict)
    t = loader.get_template('colors/index.html')
    return HttpResponse(t.render(c))
code:
index.html:

{% extends "colors/base.html" %}
{% block content %}
{% load tags %}
<div id="main_content">
    {% for error in errors %}
    {{ error }}
    {% endfor %}
    <form enctype="multipart/form-data" method="post" action="/upload/">
        {{ UploadForm }}
        <input type="submit" value="coloriffic"/>
    </form>
</div>
{% endblock %}
However, my form works properly when I use the example I posted on the last page - it just doesn't get saved to the local filesystem.

ashgromnies
Jun 19, 2004

Yeah but it doesn't give me a model to store in the database if I use that. I could write raw SQL to do it but I want to do it "the Django way".

I don't need the model right now but in the future I will because I'm going to do spidering/aggregating so it'd be nice to have the framework set up to support storing a record of each image in the database along with some metadata I calculate.

ashgromnies
Jun 19, 2004

king_kilr posted:

You are putting a form field on a model.

:facepalm: (waitaminute where'd the emoticon list in the forum rules go)

I feel dumb now. Thanks.

Adbot
ADBOT LOVES YOU

ashgromnies
Jun 19, 2004
I am trying to make an application for recipes using Django. I am starting simple and going from the tutorial but not getting the results I want. In a less strict framework I'd be able to represent what I want to easily but I'm having trouble figuring out how to do it the Django way while keeping the database clean and easy to query to prevent performance issues.

For this example, let's say I have two different models.

Recipe, and Ingredient.

A recipe has a name and a set of ingredients and an amount and measurement corresponding to each ingredient. An ingredient has only a name.

Here's an example schema of what the database in my mind would look like in 3NF:

code:
create table drinks (id int(11) auto_increment, name varchar(255));
create table ingredients (id int(11) auto_increment, name varchar(255));
create table drinks_ingredients (drinks_id int(11) not null, ingredients_id int(11) not null, amount int(11) not null, unit varchar(12));
or similar. That allows me to create only one row per a specific ingredient in the ingredients table(e.g. salt) and then use any measurement of it in the drinks_ingredients table. That way you can easily search for recipes containing a specific ingredient.

I'm having trouble figuring out how to get Django to recreate this database structure. The tutorial example with the poll application is similar but I'm not happy with the database schema because you can't use the same choice in multiple polls. This means that if you had 50 yes/no polls, you'd have "Yes" and "No" replicated in the database 50 times which, frankly, sucks.

I think I need to use a ManyToManyField for this but I'm having trouble finagling it to be the way I want. Here's what I have right now but I can't figure out where to put the amount and unit for the ingredients:

code:
class Ingredient(models.Model):
   name        = models.CharField(max_length=255)
   amount      = models.IntegerField()
   unit           = models.CharField(max_length=12)

   def __unicode__(self):
       return self.name
   class Admin:
       pass

class Recipe(models.Model):
   name        = models.CharField(max_length=255)
   ingredients = models.ManyToManyField('Ingredient')

   def __unicode__(self):
       return self.name
   class Admin:
       pass
Any ideas would be greatly appreciated :)

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