Pergunta

I am confused with contenttype in django. First let me show my codes:

models.py

class Comment(models.Model):
    owner = models.CharField(max_length=255)
    email = models.EmailField(max_length=255)
    posted_at = models.DateTimeField(auto_now_add=True)
    content = models.TextField(blank=True, null=True)
    contentmarkdown = models.TextField(help_text='Use Markdown syntax.')
    content_type = models.ForeignKey(ContentType, limit_choices_to=models.Q(
        app_label='post', model='post') | models.Q(app_label='comment',
                                                   model='comment'))
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    def save(self, *args, **kwargs):
        import markdown
        self.content = markdown.markdown(self.contentmarkdown)
        super(Comment, self).save(*args, **kwargs) 

my views.py

def create(request):
    if request.method == 'POST':
        print 'POST data: ', request.POST
        form = CommentForm(request.POST)
        #app_label, model = request.POST.get('model').split('.')
        if form.is_valid():
            comment = Comment()
        content_type = ContentType.objects.get(app_label="comment", model="comment")
        object_id = ?
        comment = Comment.objects.create(
            content_type = content_type,
            object_id = object_id,
            contentmarkdown = request.POST.get('contentmarkdown'),
            owner= request.POST.get('owner'),
            email = request.POST.get('email')
        )
        return HttpResponseRedirect("/")

urls.py

from django.conf.urls import patterns

urlpatterns = patterns('',
    (r'^create/$', 'comment.views.create'),

html

{% load i18n %}
<div class="comment">
    <form action="{% url "comment.views.create" %}" method="post">
        {% csrf_token %}
            {% for field in form %}
                {{ field.label_tag }}
                {{ field }}<p>

            {% endfor %}
        <input type="submit" value="{% trans "Submit" %}">
    </form>
</div>

forms.py

from django import forms
from comment.models import Comment
from django.forms import ModelForm

class CommentForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(CommentForm, self).__init__(*args, **kwargs)
        self.fields['owner'].label = 'Name'
        self.fields['contentmarkdown'].label = ''

    class Meta:
        model = Comment
        exclude = ['content', 'content_type', 'object_id' ]

Now my question is that : I got this error:

object_id may not be NUL

1- How can I get object_id? 2- What am I supposed to write object_id = ? 3- There is nothing like id if I write this request.POST.get(?) Please can you tell me how can I figure out object_id ?

Foi útil?

Solução

ContentType and GenericForeignKey comes in picture when you want to associate your model with many different models. Suppose you have store and you sell Clothes and Utensils. You have separate model for these two. You have a detail page for Cloth and a detail page for Utensil.

You want anyone who visits the detail page of Cloth to comment on Cloth. Similarly, you want anyone who visits the detail page of Utensil to comment on this particular Utensil. So, comment can be associated to any of these, and so you need a GenericForeignKey.

When user comments on Cloth detail page, object_id will be the id of cloth instance and content_type will be model Cloth.

When user comments on Utensil detail page, object_id will be the id of utensil instance and content_type will be model Utensil.

A comment can't exist by itself. It has to be related to something.

Read https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ again to get a better understanding of why ContentType and GFK exists.

Suppose you are in Cloth detail view, so when sending the user to cloth detail page, you know the cloth id. Send this cloth id in the context as object_id and use it in the comment form

So, your comment form looks like:

{% load i18n %}
<div class="comment">
<form action="{% url "comment.views.create" %}" method="post">
    {% csrf_token %}
        {% for field in form %}
            {{ field.label_tag }}
            {{ field }}<p>

        {% endfor %}
        <input type="hidden" value="{{object_id}}" name="object_id"/>
    <input type="submit" value="{% trans "Submit" %}">
</form>
</div>

And in Comment create view, read this object id and use it. So, in view, you say:

object_id = request.POST['object_id']
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top