Лучшая практика для тесно связанных классов для API - PullRequest
0 голосов
/ 22 марта 2012

Я сейчас использую Django с вкусным пирогом.Мне нужно реализовать API для вопросов и ответов.Я создал следующие ресурсы, связанные с моделью вопросов и ответов соответственно:

class QuestionResource(ModelResource):
    answers  = fields.ToManyField("material.resources.AnswerResource",
                                "answer_set",blank=True,full=True)

class AnswerResource(ModelResource):
    question = fields.ToOneField(QuestionResource,'question')

В моем представлении ответы относятся к вопросам, и пользователь не должен иметь возможность создавать вопрос без соответствующих ответов.В моей предыдущей итерации я использовал набор форм django, чтобы содержать информацию как для вопроса, так и для связанных ответов.Что касается вкусного пирога, то для этого сценария нет подходящего решения (насколько я знаю).

Должен ли я разрешить только запросы к ресурсу вопроса, который затем обновит соответствующие ответы, или я должен потерять пару ресурсов 2, что означает, что пользователь должен предоставить соответствующие ответы после того, как вопроссоздано.Бывший кажется мне в принципе лучше, так как последний может задавать вопросы без ответов, что в принципе никогда не должно иметь место.

1 Ответ

1 голос
/ 03 апреля 2012

Ну, я думаю, что невозможно создать два разных ресурса одновременно в RESTful API (потому что вы не можете POST к двум разным URL-адресам одновременно).Поэтому, чтобы сохранить API чистым и RESTful, я бы предпочел, чтобы вы следовали последнему подходу и позволяли создавать их отдельно (если вы не объедините их в один ресурс).Это может быть не так плохо, как кажется.

Я понимаю, что это может привести к появлению вопросов без ответов (я предполагаю, что вопрос - это первая сущность, которая должна появиться, и на этот вопрос следует ответить).Однако в вашем приложении вы могли бы преодолеть это, не работая с вопросами без ответа (например, не отображать их где-либо).

Вы могли бы даже пойти еще дальше и определить собственный класс менеджера, который отфильтровывает эти оставшиеся без ответа вопросы.по умолчанию, например, так:

# assumed that `answers` is related_name in ForeignKey from Answer to Question
class Question( models.Model )
    objects = AnsweredQuestionsManager()
    all_questions = models.Manager()

    @property
    def is_answered( self ):
        return self.answers.count() > 0

class AnsweredQuestionsManager( models.Manager ):
    def get_query_set( self ):            
        return super( AnsweredQuestionManager, self )\
            .get_query_set().annotate(
                num_answers = Count( 'answers' ) ).filter( num_answers__gt = 0 )

, тогда Question.objects.all() будет возвращать только вопросы с ответами, а Question.all_questions.all() будет также включать вопрос без ответа.

Чтобы ваша база данных была относительно чистойвы можете периодически избавляться от старых вопросов без ответа (например, с помощью Cron).

Надеюсь, это заставит вас немного больше склоняться к разделению:)

...